

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/blog/img/fluid.png">
  <link rel="icon" href="/blog/images/base.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="Airfe">
  <meta name="keywords" content="">
  
    <meta name="description" content="本文将介绍MongoDB基本的常用命令和相关概念。">
<meta property="og:type" content="article">
<meta property="og:title" content="MongoDB">
<meta property="og:url" content="https://airfe.gitee.io/blog/2023/04/01/MongoDB/index.html">
<meta property="og:site_name" content="Airfe的博客">
<meta property="og:description" content="本文将介绍MongoDB基本的常用命令和相关概念。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://markdown-1307246189.cos.ap-chongqing.myqcloud.com/pageImage/MongoDB.png">
<meta property="article:published_time" content="2023-04-01T00:00:00.000Z">
<meta property="article:modified_time" content="2024-02-26T12:22:11.254Z">
<meta property="article:author" content="Airfe">
<meta property="article:tag" content="数据库">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://markdown-1307246189.cos.ap-chongqing.myqcloud.com/pageImage/MongoDB.png">
  
  
  
    <meta name="referrer" content="no-referrer" />
  
  <title>MongoDB - Airfe的博客</title>

  <link  rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css" />



  <link  rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css" />



<!-- 主题依赖的图标库，不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_hj8rtnfg7um.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/blog/css/main.css" />


  <link id="highlight-css" rel="stylesheet" href="/blog/css/highlight.css" />
  
    <link id="highlight-css-dark" rel="stylesheet" href="/blog/css/highlight-dark.css" />
  




  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    Fluid.ctx = Object.assign({}, Fluid.ctx)
    var CONFIG = {"hostname":"airfe.gitee.io","root":"/blog/","version":"1.9.4","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false,"scope":[]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"right","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":true,"follow_dnt":true,"baidu":"699a5d71ac7179b23874a59b0666a6f6","google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":"RW68dMkEpeIOJJiBr1lPkhOS-gzGzoHsz","app_key":"P5fzMTGSJIoTaGvmgzsUHeNZ","server_url":"https://rw68dmke.lc-cn-n1-shared.com","path":"window.location.pathname","ignore_local":false}},"search_path":"/blog/local-search.xml"};

    if (CONFIG.web_analytics.follow_dnt) {
      var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
      Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
    }
  </script>
  <script  src="/blog/js/utils.js" ></script>
  <script  src="/blog/js/color-schema.js" ></script>
  

  
    <!-- Baidu Analytics -->
    <script async>
      if (!Fluid.ctx.dnt) {
        var _hmt = _hmt || [];
        (function() {
          var hm = document.createElement("script");
          hm.src = "https://hm.baidu.com/hm.js?699a5d71ac7179b23874a59b0666a6f6";
          var s = document.getElementsByTagName("script")[0];
          s.parentNode.insertBefore(hm, s);
        })();
      }
    </script>
  

  

  

  

  

  

  
    
  



  
<meta name="generator" content="Hexo 6.3.0"></head>


<body>
  

  <header>
    

<div class="header-inner" style="height: 70vh;">
  <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/blog/">
      <strong>Airfe</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/">
                <i class="iconfont icon-home-fill"></i>
                <span>首页</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/archives/">
                <i class="iconfont icon-archive-fill"></i>
                <span>归档</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/categories/">
                <i class="iconfont icon-category-fill"></i>
                <span>分类</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/tags/">
                <i class="iconfont icon-tags-fill"></i>
                <span>标签</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/about/">
                <i class="iconfont icon-user-fill"></i>
                <span>关于</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/links/">
                <i class="iconfont icon-link-fill"></i>
                <span>友链</span>
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              <i class="iconfont icon-search"></i>
            </a>
          </li>
          
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">
              <i class="iconfont icon-dark" id="color-toggle-icon"></i>
            </a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

  

<div id="banner" class="banner" parallax=true
     style="background: url('/blog/images/bg.jpg') no-repeat center center; background-size: cover;">
  <div class="full-bg-img">
    <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
      <div class="banner-text text-center fade-in-up">
        <div class="h2">
          
            <span id="subtitle" data-typed-text="MongoDB"></span>
          
        </div>

        
          
  <div class="mt-3">
    
    
      <span class="post-meta">
        <i class="iconfont icon-date-fill" aria-hidden="true"></i>
        <time datetime="2023-04-01 08:00" pubdate>
          2023年04月01日
        </time>
      </span>
    
  </div>

  <div class="mt-1">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-chart"></i>
        
          27k 字
        
      </span>
    

    
      <span class="post-meta mr-2">
        <i class="iconfont icon-clock-fill"></i>
        
        
        
          222 分钟
        
      </span>
    

    
    
  </div>


        
      </div>

      
    </div>
  </div>
</div>

</div>

  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="side-col d-none d-lg-block col-lg-2">
      

    </div>

    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">MongoDB</h1>
            
            
              <div class="markdown-body">
                
                <h1 id="1-MongoDB-相关概念"><a href="#1-MongoDB-相关概念" class="headerlink" title="*1.MongoDB 相关概念"></a>*1.MongoDB 相关概念</h1><h2 id="1-1-业务场景"><a href="#1-1-业务场景" class="headerlink" title="1.1 业务场景"></a>1.1 业务场景</h2><p>传统的关系型数据库 (比如 MySQL), 在数据操作的”三高”需求以及对应的 Web 2.0 网站需求面前, 会有”力不从心”的感觉</p>
<p>所谓的三高需求:</p>
<p><strong>高并发, 高性能, 高可用</strong>, 简称三高</p>
<ul>
<li>High Performance: 对数据库的高并发读写的要求</li>
<li>High Storage: 对海量数据的高效率存储和访问的需求</li>
<li>High Scalability &amp;&amp; High Available: 对数据的高扩展性和高可用性的需求</li>
</ul>
<p><strong>而 MongoDB 可以应对三高需求</strong></p>
<p>具体的应用场景:</p>
<ul>
<li>社交场景, 使用 MongoDB 存储存储用户信息, 以及用户发表的朋友圈信息, 通过地理位置索引实现附近的人, 地点等功能.</li>
<li>游戏场景, 使用 MongoDB 存储游戏用户信息, 用户的装备, 积分等直接以内嵌文档的形式存储, 方便查询, 高效率存储和访问.</li>
<li>物流场景, 使用 MongoDB 存储订单信息, 订单状态在运送过程中会不断更新, 以 MongoDB 内嵌数组的形式来存储, 一次查询就能将订单所有的变更读取出来.</li>
<li>物联网场景, 使用 MongoDB 存储所有接入的智能设备信息, 以及设备汇报的日志信息, 并对这些信息进行多维度的分析.</li>
<li>视频直播, 使用 MongoDB 存储用户信息, 点赞互动信息等.</li>
</ul>
<p>这些应用场景中, 数据操作方面的共同点有: </p>
<ol>
<li>数据量大</li>
<li>写入操作频繁</li>
<li>价值较低的数据, 对<strong>事务性</strong>要求不高</li>
</ol>
<p>对于这样的数据, 更适合用 MongoDB 来实现数据存储</p>
<p>那么我们<strong>什么时候选择 MongoDB 呢?</strong></p>
<p>除了架构选型上, 除了上述三个特点之外, 还要考虑下面这些问题:</p>
<ul>
<li>应用不需要事务及复杂 JOIN 支持</li>
<li>新应用, 需求会变, 数据模型无法确定, 想快速迭代开发</li>
<li>应用需要 2000 - 3000 以上的读写QPS（更高也可以）</li>
<li>应用发展迅速, 需要能快速水平扩展</li>
<li>应用要求存储的数据不丢失</li>
<li>应用需要 <code>99.999%</code> 高可用</li>
<li>应用需要大量的地理位置查询, 文本查询</li>
</ul>
<p>如果上述有1个符合, 可以考虑 MongoDB, 2个及以上的符合, 选择 MongoDB 绝不会后悔.</p>
<blockquote>
<p>如果用MySQL呢?</p>
<p>相对MySQL, 可以以更低的成本解决问题（包括学习, 开发, 运维等成本）</p>
</blockquote>
<h2 id="1-2-MongoDB-简介"><a href="#1-2-MongoDB-简介" class="headerlink" title="1.2 MongoDB 简介"></a>1.2 MongoDB 简介</h2><blockquote>
<p>MongoDB是一个开源, 高性能, 无模式的文档型数据库, 当初的设计就是用于简化开发和方便扩展, 是NoSQL数据库产品中的一种.是最 像关系型数据库（MySQL）的非关系型数据库. 它支持的数据结构非常松散, 是一种类似于 JSON 的 格式叫BSON, 所以它既可以存储比较复杂的数据类型, 又相当的灵活. MongoDB中的记录是一个文档, 它是一个由字段和值对（ﬁeld:value）组成的数据结构.MongoDB文档类似于JSON对象, 即一个文档认 为就是一个对象.字段的数据类型是字符型, 它的值除了使用基本的一些类型外, 还可以包括其他文档, 普通数组和文档数组.</p>
</blockquote>
<h2 id="1-3-体系结构"><a href="#1-3-体系结构" class="headerlink" title="1.3 体系结构"></a>1.3 体系结构</h2><p><img src="" srcset="/blog/img/loading.gif" lazyload data-original="https://markdown-1307246189.cos.ap-chongqing.myqcloud.com/%20markdown/image-20230427221158812.png" alt="image-20230427221158812"></p>
<p><img src="" srcset="/blog/img/loading.gif" lazyload data-original="https://markdown-1307246189.cos.ap-chongqing.myqcloud.com/%20markdown/image-20230427221228362.png" alt="image-20230427221228362"></p>
<h2 id="1-4-数据模型"><a href="#1-4-数据模型" class="headerlink" title="1.4 数据模型"></a>1.4 数据模型</h2><p>MongoDB的最小存储单位就是文档(document)对象。文档(document)对象对应于关系型数据库的行。数据在MongoDB中以</p>
<p>BSON（Binary-JSON）文档的格式存储在磁盘上。</p>
<p>BSON（Binary Serialized Document Format）是一种类json的一种二进制形式的存储格式，简称Binary JSON。BSON和JSON一样，支持</p>
<p>内嵌的文档对象和数组对象，但是BSON有JSON没有的一些数据类型，如Date和BinData类型。</p>
<p>BSON采用了类似于 C 语言结构体的名称、对表示方法，支持内嵌的文档对象和数组对象，具有轻量性、可遍历性、高效性的三个特点，可</p>
<p>以有效描述非结构化数据和结构化数据。这种格式的优点是灵活性高，但它的缺点是空间利用率不是很理想。</p>
<p>Bson中，除了基本的JSON类型：string,integer,boolean,double,null,array和object，mongo还使用了特殊的数据类型。这些类型包括</p>
<p>date,object id,binary data,regular expression 和code。每一个驱动都以特定语言的方式实现了这些类型，查看你的驱动的文档来获取详</p>
<p>细信息。</p>
<p>BSON数据类型参考列表：</p>
<p><img src="" srcset="/blog/img/loading.gif" lazyload data-original="https://markdown-1307246189.cos.ap-chongqing.myqcloud.com/%20markdown/image-20230427221303717.png" alt="image-20230427221303717"></p>
<p>提示：</p>
<p>shell默认使用64位浮点型数值。{“x”：3.14}或{“x”：3}。对于整型值，可以使用NumberInt（4字节符号整数）或NumberLong（8字节符</p>
<p>号整数），{“x”:NumberInt(“3”)}{“x”:NumberLong(“3”)}</p>
<h2 id="1-5-MongoDB的特点"><a href="#1-5-MongoDB的特点" class="headerlink" title="1.5 MongoDB的特点"></a>1.5 MongoDB的特点</h2><p>高性能、高可用性、高扩展性、丰富的查询支持</p>
<h1 id="2-单机部署"><a href="#2-单机部署" class="headerlink" title="2.单机部署"></a>2.单机部署</h1><h2 id="2-1-Windows系统中的安装启动"><a href="#2-1-Windows系统中的安装启动" class="headerlink" title="2.1 Windows系统中的安装启动"></a>2.1 Windows系统中的安装启动</h2><h3 id="第一步：下载安装包"><a href="#第一步：下载安装包" class="headerlink" title="第一步：下载安装包"></a>第一步：下载安装包</h3><p>MongoDB 提供了可用于 32 位和 64 位系统的预编译二进制包，你可以从MongoDB官网下载安装，MongoDB 预编译二进制包下载地址：<a target="_blank" rel="noopener" href="https://www.mongodb.com/try/download/communit">https://www.mongodb.com/try/download/communit</a>  </p>
<p>或直接从网盘获取</p>
<h3 id="第二步：解压安装启动服务"><a href="#第二步：解压安装启动服务" class="headerlink" title="第二步：解压安装启动服务"></a>第二步：解压安装启动服务</h3><p>在解压目录中bin同级目录下，手动建立一个目录用于存放数据文件，如 data&#x2F;db</p>
<h4 id="方式1：命令行参数方式启动服务（平时采用）"><a href="#方式1：命令行参数方式启动服务（平时采用）" class="headerlink" title="方式1：命令行参数方式启动服务（平时采用）"></a>方式1：命令行参数方式启动服务（平时采用）</h4><p>在 bin 目录中打开cmd，输入如下命令：</p>
<figure class="highlight jboss-cli"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs jboss-cli">mongod <span class="hljs-params">--dbpath=</span><span class="hljs-string">..</span>\data\db<br></code></pre></td></tr></table></figure>

<p>我们在启动信息中可以看到，mongoDB的默认端口是<strong>27017</strong>，如果我们想改变默认的启动端口，可以通过–port来指定端口。</p>
<p>为了方便我们每次启动，可以将安装目录的bin目录设置到环境变量的path中， bin 目录下是一些常用命令，比如 mongod 启动服务用的，</p>
<p>mongo 客户端连接服务用的。</p>
<h4 id="方式2：配置文件方式启动服务-部署时采用）"><a href="#方式2：配置文件方式启动服务-部署时采用）" class="headerlink" title="方式2：配置文件方式启动服务(部署时采用）"></a>方式2：配置文件方式启动服务(部署时采用）</h4><p>在解压目录bin同级目录新建 config 文件夹，该文件夹中新建配置文件 mongod.conf ，参考如下：</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">storage:</span><br>  <span class="hljs-comment">#The directory where the mongod instance stores its data.Default Value is &quot;\data\db&quot; on Windows.</span><br>  <span class="hljs-attr">dbPath:</span> <span class="hljs-string">D:\02_Server\DBServer\mongodb-win32-x86_64-2008plus-ssl-4.0.1\data</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>dbPath是自己建的数据文件的具体位置</p>
</blockquote>
<p>启动方式在bin目录下打开cmd</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs awk">mongod -f ..<span class="hljs-regexp">/conf/m</span>ongod.conf<br>或<br>mongod --config ..<span class="hljs-regexp">/conf/m</span>ongod.conf<br></code></pre></td></tr></table></figure>

<p>更多参数配置：</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">systemLog:</span><br>    <span class="hljs-attr">destination:</span> <span class="hljs-string">file</span><br>    <span class="hljs-comment">#The path of the log file to which mongod or mongos should send all diagnostic logging information</span><br>    <span class="hljs-attr">path:</span> <span class="hljs-string">&quot;D:/02_Server/DBServer/mongodb-win32-x86_64-2008plus-ssl-4.0.1/log/mongod.log&quot;</span><br>    <span class="hljs-attr">logAppend:</span> <span class="hljs-literal">true</span><br><span class="hljs-attr">storage:</span><br>    <span class="hljs-attr">journal:</span><br>        <span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span><br>    <span class="hljs-comment">#The directory where the mongod instance stores its data.Default Value is &quot;/data/db&quot;.</span><br>    <span class="hljs-attr">dbPath:</span> <span class="hljs-string">&quot;D:/02_Server/DBServer/mongodb-win32-x86_64-2008plus-ssl-4.0.1/data&quot;</span><br><span class="hljs-attr">net:</span><br>    <span class="hljs-comment">#bindIp: 127.0.0.1</span><br>    <span class="hljs-attr">port:</span> <span class="hljs-number">27017</span><br><span class="hljs-attr">setParameter:</span><br>    <span class="hljs-attr">enableLocalhostAuthBypass:</span> <span class="hljs-literal">false</span><br></code></pre></td></tr></table></figure>

<h2 id="2-2-Shell连接-mongo命令"><a href="#2-2-Shell连接-mongo命令" class="headerlink" title="2.2 Shell连接(mongo命令)"></a>2.2 Shell连接(mongo命令)</h2><p>在命令提示符输入以下shell命令即可完成登陆</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs routeros">mongo<br>或<br>mongo <span class="hljs-attribute">--host</span>=127.0.0.1 <span class="hljs-attribute">--port</span>=27017<br></code></pre></td></tr></table></figure>

<p>查看已经有的数据库</p>
<figure class="highlight dart"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs dart">&gt;<span class="hljs-keyword">show</span> databases<br></code></pre></td></tr></table></figure>

<p>退出mongodb</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk"><span class="hljs-keyword">exit</span><br></code></pre></td></tr></table></figure>

<p>更多参数可以通过帮助查看：</p>
<figure class="highlight ada"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ada">mongo <span class="hljs-comment">--help</span><br></code></pre></td></tr></table></figure>

<p>提示：</p>
<p>MongoDB javascript shell是一个基于javascript的解释器，故是支持js程序的。</p>
<h2 id="2-3-Compass-图形化界面客户端"><a href="#2-3-Compass-图形化界面客户端" class="headerlink" title="2.3 Compass-图形化界面客户端"></a>2.3 Compass-图形化界面客户端</h2><p>到MongoDB官网下载MongoDB Compass，</p>
<p>地址：<a target="_blank" rel="noopener" href="https://www.mongodb.com/download-center/v2/compass?initial=true">https://www.mongodb.com/download-center/v2/compass?initial=true</a></p>
<p>或直接从网盘获取</p>
<p>执行里面的 MongoDBCompassCommunity.exe 文件即可。</p>
<h2 id="2-4-Linux系统中的安装启动和连接"><a href="#2-4-Linux系统中的安装启动和连接" class="headerlink" title="2.4 Linux系统中的安装启动和连接"></a>2.4 Linux系统中的安装启动和连接</h2><p>目标：在Linux中部署一个单机的MongoDB，作为生产环境下使用。</p>
<p>提示：和Windows下操作差不多。</p>
<p>步骤如下：</p>
<p>（1）先到官网下载压缩包 mongod-linux-x86_64-4.0.10.tgz 。</p>
<p>（2）上传压缩包到Linux中，解压到当前目录：</p>
<figure class="highlight plaintext"><figcaption><span>-xvf mongodb-linux-x86_64-4.0.10.tgz</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs tar">tar -xvf mongodb-linux-x86_64-4.0.10.tgz<br></code></pre></td></tr></table></figure>

<p>（3）移动解压后的文件夹到指定的目录中：</p>
<figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">mv</span> mongodb-linux-x86_64-<span class="hljs-number">4</span>.<span class="hljs-number">0</span>.<span class="hljs-number">10</span> /usr/local/mongodb<br></code></pre></td></tr></table></figure>

<p>（4）新建几个目录，分别用来存储数据和日志：</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs awk"><span class="hljs-comment">#数据存储目录</span><br>mkdir -p <span class="hljs-regexp">/mongodb/</span>single<span class="hljs-regexp">/data/</span>db<br><span class="hljs-comment">#日志存储目录</span><br>mkdir -p <span class="hljs-regexp">/mongodb/</span>single/log<br></code></pre></td></tr></table></figure>

<p>（5）新建并修改配置文件</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">vi <span class="hljs-regexp">/mongodb/</span>single/mongod.conf<br></code></pre></td></tr></table></figure>

<p>配置文件的内容如下：</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">systemLog:</span><br>    <span class="hljs-comment">#MongoDB发送所有日志输出的目标指定为文件</span><br>    <span class="hljs-comment"># #The path of the log file to which mongod or mongos should send all diagnostic logging information</span><br>    <span class="hljs-attr">destination:</span> <span class="hljs-string">file</span><br>    <span class="hljs-comment">#mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径</span><br>    <span class="hljs-attr">path:</span> <span class="hljs-string">&quot;/mongodb/single/log/mongod.log&quot;</span><br>    <span class="hljs-comment">#当mongos或mongod实例重新启动时，mongos或mongod会将新条目附加到现有日志文件的末尾。</span><br>    <span class="hljs-attr">logAppend:</span> <span class="hljs-literal">true</span><br><span class="hljs-attr">storage:</span><br>    <span class="hljs-comment">#mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。</span><br>    <span class="hljs-comment">##The directory where the mongod instance stores its data.Default Value is &quot;/data/db&quot;.</span><br>    <span class="hljs-attr">dbPath:</span> <span class="hljs-string">&quot;/mongodb/single/data/db&quot;</span><br>    <span class="hljs-attr">journal:</span><br>    <span class="hljs-comment">#启用或禁用持久性日志以确保数据文件保持有效和可恢复。</span><br>      <span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span><br><span class="hljs-attr">processManagement:</span><br>    <span class="hljs-comment">#启用在后台运行mongos或mongod进程的守护进程模式。</span><br>    <span class="hljs-attr">fork:</span> <span class="hljs-literal">true</span>  <br><span class="hljs-attr">net:</span><br>    <span class="hljs-comment">#服务实例绑定的IP，默认是localhost</span><br>    <span class="hljs-attr">bindIp:</span> <span class="hljs-string">localhost,192.168.0.2</span><br>    <span class="hljs-comment">#bindIp</span><br>    <span class="hljs-comment">#绑定的端口，默认是27017</span><br>    <span class="hljs-attr">port:</span> <span class="hljs-number">27017</span><br></code></pre></td></tr></table></figure>

<p>(6) 启动MongoDB服务</p>
<figure class="highlight gradle"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs gradle">[root@bobohost single]# <span class="hljs-regexp">/usr/</span>local<span class="hljs-regexp">/mongodb/</span>bin<span class="hljs-regexp">/mongod -f /m</span>ongodb<span class="hljs-regexp">/single/m</span>ongod.conf<br>about to fork child process, waiting until server is ready <span class="hljs-keyword">for</span> connections.<br>forked process: <span class="hljs-number">90384</span><br>child process started successfully, parent exiting<br></code></pre></td></tr></table></figure>

<p>注意：</p>
<p>如果启动后不是 successfully ，则是启动失败了。原因基本上就是配置文件有问题。</p>
<p>通过进程来查看服务是否启动了：</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs awk">[root@bobohost single]<span class="hljs-comment"># ps -ef |grep mongod</span><br>root <span class="hljs-number">90384</span> <span class="hljs-number">1</span> <span class="hljs-number">0</span> <span class="hljs-number">8</span>月<span class="hljs-number">26</span> ? <span class="hljs-number">00</span>:<span class="hljs-number">02</span>:<span class="hljs-number">13</span> <span class="hljs-regexp">/usr/</span>local<span class="hljs-regexp">/mongdb/</span>bin<span class="hljs-regexp">/mongod -f /m</span>ongodb<span class="hljs-regexp">/single/m</span>ongod.conf<br></code></pre></td></tr></table></figure>

<p>（7）分别使用mongo命令和compass工具来连接测试。</p>
<p>提示：如果远程连接不上，需要配置防火墙放行，或直接关闭linux防火墙</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs shell"><span class="hljs-meta prompt_">#</span><span class="language-bash">查看防火墙状态</span><br>systemctl status firewalld<br><span class="hljs-meta prompt_">#</span><span class="language-bash">临时关闭防火墙</span><br>systemctl stop firewalld<br><span class="hljs-meta prompt_">#</span><span class="language-bash">开机禁止启动防火墙</span><br>systemctl disable firewalld<br></code></pre></td></tr></table></figure>

<p>（8）停止关闭服务</p>
<p>停止服务的方式有两种：快速关闭和标准关闭，下面依次说明：</p>
<p>（一）快速关闭方法（快速，简单，数据可能会出错）</p>
<p>目标：通过系统的kill命令直接杀死进程：</p>
<p>杀完要检查一下，避免有的没有杀掉。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs shell"><span class="hljs-meta prompt_">#</span><span class="language-bash">通过进程编号关闭节点</span><br>kill -2 54410<br></code></pre></td></tr></table></figure>

<p>【补充】</p>
<p>如果一旦是因为数据损坏，则需要进行如下操作（了解）：</p>
<p>1）删除lock文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">rm -f /mongodb/single/data/db/*.lock<br></code></pre></td></tr></table></figure>

<p>2）修复数据：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">/usr/local/mongdb/bin/mongod --repair --dbpath=/mongodb/single/data/db<br></code></pre></td></tr></table></figure>

<p>（二）标准的关闭方法（数据不容易出错，但麻烦）：</p>
<p>目标：通过mongo客户端中的shutdownServer命令来关闭服务</p>
<p>主要的操作步骤参考如下：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs shell">//客户端登录服务，注意，这里通过localhost登录，如果需要远程登录，必须先登录认证才行。<br>mongo --port 27017<br><span class="hljs-meta prompt_">//#</span><span class="language-bash">切换到admin库</span><br>use admin<br>//关闭服务<br>db.shutdownServer()<br></code></pre></td></tr></table></figure>

<h1 id="3-基本常用命令"><a href="#3-基本常用命令" class="headerlink" title="3 基本常用命令"></a>3 基本常用命令</h1><p>推荐参考：<a target="_blank" rel="noopener" href="https://www.csdn.net/tags/OtTaIgzsOTQ1Ny1ibG9n.html">https://www.csdn.net/tags/OtTaIgzsOTQ1Ny1ibG9n.html</a></p>
<h2 id="3-1-案例需求"><a href="#3-1-案例需求" class="headerlink" title="3.1 案例需求"></a>3.1 案例需求</h2><p>存放文章评论的数据存放到MongoDB中，数据结构参考如下：</p>
<p>数据库：articledb</p>
<table>
<thead>
<tr>
<th><strong>专栏文章评论</strong></th>
<th><strong>comment</strong></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody><tr>
<td>字段名称</td>
<td>字段含义</td>
<td>ObjectId或String</td>
<td>Mongo的主键的字段</td>
</tr>
<tr>
<td>_id</td>
<td>ID</td>
<td>ObjectId或String</td>
<td>Mongo的主键的字段</td>
</tr>
<tr>
<td>articleid</td>
<td>文章ID</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>content</td>
<td>评论内容</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>userid</td>
<td>评论人ID</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>nickname</td>
<td>评论人昵称</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>createdatetime</td>
<td>评论的日期时间</td>
<td>Date</td>
<td></td>
</tr>
<tr>
<td>likenum</td>
<td>点赞数</td>
<td>Int32</td>
<td></td>
</tr>
<tr>
<td>replynum</td>
<td>回复数</td>
<td>Int32</td>
<td></td>
</tr>
<tr>
<td>state</td>
<td>状态</td>
<td>String</td>
<td>0：不可见；1：可见；</td>
</tr>
<tr>
<td>parentid</td>
<td>上级ID</td>
<td>String</td>
<td>如果为0表示文章的顶级评论</td>
</tr>
</tbody></table>
<h2 id="3-2-数据库操作"><a href="#3-2-数据库操作" class="headerlink" title="3.2 数据库操作"></a>3.2 数据库操作</h2><h3 id="3-2-1-选择和创建数据库"><a href="#3-2-1-选择和创建数据库" class="headerlink" title="3.2.1 选择和创建数据库"></a>3.2.1 选择和创建数据库</h3><p>选择和创建数据库的语法格式：</p>
<figure class="highlight actionscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs actionscript"><span class="hljs-keyword">use</span> 数据库名称<br></code></pre></td></tr></table></figure>

<p>如果数据库不存在则自动创建，例如，以下语句创建 spitdb 数据库：</p>
<figure class="highlight actionscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs actionscript"><span class="hljs-keyword">use</span> articledb<br></code></pre></td></tr></table></figure>

<p>查看有权限查看的所有的数据库命令</p>
<figure class="highlight dart"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs dart"><span class="hljs-keyword">show</span> dbs<br>或<br><span class="hljs-keyword">show</span> databases<br></code></pre></td></tr></table></figure>

<blockquote>
<p>注意 在 MongoDB 中，集合只有在内容插入后才会创建! 就是说，创建集合(数据表)后要再插入一个文档(记录)，集合才会真正创建。</p>
</blockquote>
<h4 id="查看当前正在使用的数据库命令"><a href="#查看当前正在使用的数据库命令" class="headerlink" title="查看当前正在使用的数据库命令"></a>查看当前正在使用的数据库命令</h4><figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ebnf"><span class="hljs-attribute">db</span><br></code></pre></td></tr></table></figure>

<p>MongoDB 中默认的数据库为 test，如果你没有选择数据库，集合将存放在 test 数据库中。</p>
<p>另外：</p>
<p>数据库名可以是满足以下条件的任意UTF-8字符串。</p>
<ul>
<li>不能是空字符串（””)。</li>
<li>不得含有’ ‘（空格)、.、$、&#x2F;、\和\0 (空字符)。</li>
<li>应全部小写。</li>
<li>最多64字节。</li>
</ul>
<p>有一些数据库名是保留的，可以直接访问这些有特殊作用的数据库。</p>
<p><strong>admin</strong>： 从权限的角度来看，这是”root”数据库。要是将一个用户添加到这个数据库，这个用户自动继承所有数据库的权限。一些特</p>
<p>定的服务器端命令也只能从这个数据库运行，比如列出所有的数据库或者关闭服务器。</p>
<p><strong>local:</strong> 这个数据永远不会被复制，可以用来存储限于本地单台服务器的任意集合</p>
<p><strong>confifig</strong>: 当Mongo用于分片设置时，confifig数据库在内部使用，用于保存分片的相关信息。</p>
<h3 id="3-2-2-数据库的删除"><a href="#3-2-2-数据库的删除" class="headerlink" title="3.2.2 数据库的删除"></a>3.2.2 数据库的删除</h3><p>MongoDB 删除数据库的语法格式如下：</p>
<figure class="highlight gcode"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs gcode">db.dropDatabase<span class="hljs-comment">()</span><br></code></pre></td></tr></table></figure>

<p>提示：主要用来删除已经持久化的数据库</p>
<h2 id="3-3-集合操作"><a href="#3-3-集合操作" class="headerlink" title="3.3 集合操作"></a>3.3 集合操作</h2><p>集合，类似关系型数据库中的表。</p>
<p>可以显示的创建，也可以隐式的创建.</p>
<p>MongoDB 中默认的数据库为 test，如果你没有创建新的数据库，集合将存放在 test 数据库中。</p>
<h3 id="3-3-1-集合的显式创建（了解）"><a href="#3-3-1-集合的显式创建（了解）" class="headerlink" title="3.3.1 集合的显式创建（了解）"></a>3.3.1 集合的显式创建（了解）</h3><p>基本语法格式：</p>
<figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs reasonml">db.create<span class="hljs-constructor">Collection(<span class="hljs-params">name</span>)</span><br></code></pre></td></tr></table></figure>

<p>参数说明：</p>
<p>name: 要创建的集合名称</p>
<p>例如：创建一个名为 mycollection 的普通集合。</p>
<figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs reasonml">db.create<span class="hljs-constructor">Collection(<span class="hljs-string">&quot;mycollection&quot;</span>)</span><br></code></pre></td></tr></table></figure>

<p>查看当前数据库中的表：show tables命令</p>
<figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs pgsql"><span class="hljs-keyword">show</span> collections<br>或<br><span class="hljs-keyword">show</span> <span class="hljs-keyword">tables</span><br></code></pre></td></tr></table></figure>

<p>集合的命名规范：</p>
<p>集合名不能是空字符串””。</p>
<p>集合名不能含有\0字符（空字符)，这个字符表示集合名的结尾。</p>
<p>集合名不能以”system.”开头，这是为系统集合保留的前缀。</p>
<p>用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含，这是因为某些系统生成的集合中包含该字符。除</p>
<p>非你要访问这种系统创建的集合，否则千万不要在名字里出现$。</p>
<h3 id="3-3-2-集合的隐式创建"><a href="#3-3-2-集合的隐式创建" class="headerlink" title="3.3.2 集合的隐式创建"></a>3.3.2 集合的隐式创建</h3><p>当向一个集合中插入一个文档的时候，如果集合不存在，则会自动创建集合。</p>
<p>详见 文档的插入 章节。</p>
<p>提示：通常我们使用隐式创建文档即可。</p>
<h3 id="3-3-3-集合的删除"><a href="#3-3-3-集合的删除" class="headerlink" title="3.3.3 集合的删除"></a>3.3.3 集合的删除</h3><p>集合删除语法格式如下：</p>
<figure class="highlight stata"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs stata"><span class="hljs-keyword">db</span>.collection.<span class="hljs-keyword">drop</span>()<br>或<br><span class="hljs-keyword">db</span>.集合.<span class="hljs-keyword">drop</span>()<br></code></pre></td></tr></table></figure>

<p><strong>返回值</strong></p>
<p>如果成功删除选定集合，则 drop() 方法返回 true，否则返回 false。</p>
<p>例如：要删除mycollection集合</p>
<figure class="highlight stata"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stata"><span class="hljs-keyword">db</span>.mycollection.<span class="hljs-keyword">drop</span>()<br></code></pre></td></tr></table></figure>

<h2 id="3-4-文档基本CRUD"><a href="#3-4-文档基本CRUD" class="headerlink" title="3.4 文档基本CRUD"></a>3.4 文档基本CRUD</h2><p>文档（document）的数据结构和 JSON 基本一样。</p>
<p>所有存储在集合中的数据都是 BSON 格式。</p>
<h3 id="3-4-1-文档的插入"><a href="#3-4-1-文档的插入" class="headerlink" title="3.4.1 文档的插入"></a>3.4.1 文档的插入</h3><h4 id="（1）单个文档插入"><a href="#（1）单个文档插入" class="headerlink" title="（1）单个文档插入"></a>（1）单个文档插入</h4><p>使用insert() 或 save() 方法向集合中插入文档，语法如下：</p>
<figure class="highlight xquery"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs xquery">db<span class="hljs-built_in">.collection</span>.<span class="hljs-keyword">insert</span>(<br>    &lt;<span class="hljs-keyword">document</span> or array of documents&gt;,<br>    &#123;<br>        writeConcern: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">document</span>&gt;</span>,</span><br><span class="language-xml">        ordered: </span><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">boolean</span>&gt;</span></span><br><span class="language-xml">    &#125;</span><br><span class="language-xml">)</span><br></code></pre></td></tr></table></figure>

<p>参数：</p>
<table>
<thead>
<tr>
<th><strong>Parameter</strong></th>
<th><strong>Type</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody><tr>
<td>document</td>
<td>document or array</td>
<td>要插入到集合中的文档或文档数组。（(json格式）</td>
</tr>
<tr>
<td>writeConcern</td>
<td>document</td>
<td>Optional. A document expressing the write concern. Omit to use the default write concern. See Write Concern.Do not explicitly set the write concern for the operation if run in a transaction. To use write concern with transactions, see Transactions and Write Concern.</td>
</tr>
<tr>
<td>ordered</td>
<td>boolean</td>
<td>可选。如果为真，则按顺序插入数组中的文档，如果其中一个文档出现错误，MongoDB将返回而</td>
</tr>
</tbody></table>
<p>【示例】</p>
<p>要向comment的集合(表)中插入一条测试数据： </p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs shell">db.comment.insert(&#123;&quot;articleid&quot;:&quot;100000&quot;,&quot;content&quot;:&quot;今天天气真好，阳光明媚&quot;,&quot;userid&quot;:&quot;1001&quot;,&quot;nickname&quot;:&quot;Rose&quot;,<br>&quot;createdatetime&quot;:new Date(),&quot;likenum&quot;:NumberInt(10),&quot;state&quot;:null&#125;)<br></code></pre></td></tr></table></figure>

<p>提示：</p>
<p>1）comment集合如果不存在，则会隐式创建</p>
<p>2）mongo中的数字，默认情况下是double类型，如果要存整型，必须使用函数NumberInt(整型数字)，否则取出来就有问题了。</p>
<p>3）插入当前日期使用 new Date()</p>
<p>4）插入的数据没有指定 _id ，会自动生成主键值</p>
<p>5）如果某字段没值，可以赋值为null，或不写该字段。</p>
<p>执行后，如下，说明插入一个数据成功了。</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus"><span class="hljs-function"><span class="hljs-title">WriteResult</span><span class="hljs-params">(&#123; <span class="hljs-string">&quot;nInserted&quot;</span> : <span class="hljs-number">1</span> &#125;)</span></span><br></code></pre></td></tr></table></figure>

<p>注意：</p>
<ol>
<li><p>文档中的键&#x2F;值对是有序的。</p>
</li>
<li><p>文档中的值不仅可以是在双引号里面的字符串，还可以是其他几种数据类型（甚至可以是整个嵌入的文档)。</p>
</li>
<li><p>MongoDB区分类型和大小写。</p>
</li>
<li><p>MongoDB的文档不能有重复的键。</p>
</li>
<li><p>文档的键是字符串。除了少数例外情况，键可以使用任意UTF-8字符。</p>
</li>
</ol>
<p>文档键命名规范：</p>
<ul>
<li>键不能含有\0 (空字符)。这个字符用来表示键的结尾。</li>
<li>.和$有特别的意义，只有在特定环境下才能使用。</li>
<li>以下划线”_”开头的键是保留的(不是严格要求的)。</li>
</ul>
<h4 id="（2）批量插入"><a href="#（2）批量插入" class="headerlink" title="（2）批量插入"></a>（2）批量插入</h4><p>语法：</p>
<figure class="highlight pf"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs pf">db.collection.insertM<span class="hljs-literal">any</span>(<br>    [ <span class="hljs-variable">&lt;document 1&gt;</span> , <span class="hljs-variable">&lt;document 2&gt;</span>, ... ],<br>        &#123;<br>            writeConcern: <span class="hljs-variable">&lt;document&gt;</span>,<br>            ordered: <span class="hljs-variable">&lt;boolean&gt;</span><br>        &#125;<br>)<br></code></pre></td></tr></table></figure>

<p>参数：</p>
<table>
<thead>
<tr>
<th><strong>Parameter</strong></th>
<th><strong>Type</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody><tr>
<td>document</td>
<td>document or array</td>
<td>要插入到集合中的文档或文档数组。（(json格式）</td>
</tr>
<tr>
<td>writeConcern</td>
<td>document</td>
<td>Optional. A document expressing the write concern. Omit to use the default write concern. See Write Concern.Do not explicitly set the write concern for the operation if run in a transaction. To use write concern with transactions, see Transactions and Write Concern.</td>
</tr>
<tr>
<td>ordered</td>
<td>boolean</td>
<td>可选。如果为真，则按顺序插入数组中的文档，如果其中一个文档出现错误，MongoDB将返回而</td>
</tr>
</tbody></table>
<p>【示例】</p>
<p>批量插入多条文章评论：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs js">db.<span class="hljs-property">comment</span>.<span class="hljs-title function_">insertMany</span>([<br>   &#123;<span class="hljs-string">&quot;_id&quot;</span>:<span class="hljs-string">&quot;1&quot;</span>,<span class="hljs-string">&quot;articleid&quot;</span>:<span class="hljs-string">&quot;100001&quot;</span>,<span class="hljs-string">&quot;content&quot;</span>:<span class="hljs-string">&quot;我们不应该把清晨浪费在手机上，健康很重要，一杯温水幸福你我</span><br><span class="hljs-string">他。&quot;</span>,<span class="hljs-string">&quot;userid&quot;</span>:<span class="hljs-string">&quot;1002&quot;</span>,<span class="hljs-string">&quot;nickname&quot;</span>:<span class="hljs-string">&quot;相忘于江湖&quot;</span>,<span class="hljs-string">&quot;createdatetime&quot;</span>:<span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(<span class="hljs-string">&quot;2019-08-</span><br><span class="hljs-string">05T22:08:15.522Z&quot;</span>),<span class="hljs-string">&quot;likenum&quot;</span>:<span class="hljs-title class_">NumberInt</span>(<span class="hljs-number">1000</span>),<span class="hljs-string">&quot;state&quot;</span>:<span class="hljs-string">&quot;1&quot;</span>&#125;,<br>   &#123;<span class="hljs-string">&quot;_id&quot;</span>:<span class="hljs-string">&quot;2&quot;</span>,<span class="hljs-string">&quot;articleid&quot;</span>:<span class="hljs-string">&quot;100001&quot;</span>,<span class="hljs-string">&quot;content&quot;</span>:<span class="hljs-string">&quot;我夏天空腹喝凉开水，冬天喝温开水&quot;</span>,<span class="hljs-string">&quot;userid&quot;</span>:<span class="hljs-string">&quot;1005&quot;</span>,<span class="hljs-string">&quot;nickname&quot;</span>:<span class="hljs-string">&quot;伊人憔</span><br><span class="hljs-string">悴&quot;</span>,<span class="hljs-string">&quot;createdatetime&quot;</span>:<span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(<span class="hljs-string">&quot;2019-08-05T23:58:51.485Z&quot;</span>),<span class="hljs-string">&quot;likenum&quot;</span>:<span class="hljs-title class_">NumberInt</span>(<span class="hljs-number">888</span>),<span class="hljs-string">&quot;state&quot;</span>:<span class="hljs-string">&quot;1&quot;</span>&#125;,<br>   &#123;<span class="hljs-string">&quot;_id&quot;</span>:<span class="hljs-string">&quot;3&quot;</span>,<span class="hljs-string">&quot;articleid&quot;</span>:<span class="hljs-string">&quot;100001&quot;</span>,<span class="hljs-string">&quot;content&quot;</span>:<span class="hljs-string">&quot;我一直喝凉开水，冬天夏天都喝。&quot;</span>,<span class="hljs-string">&quot;userid&quot;</span>:<span class="hljs-string">&quot;1004&quot;</span>,<span class="hljs-string">&quot;nickname&quot;</span>:<span class="hljs-string">&quot;杰克船</span><br><span class="hljs-string">长&quot;</span>,<span class="hljs-string">&quot;createdatetime&quot;</span>:<span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(<span class="hljs-string">&quot;2019-08-06T01:05:06.321Z&quot;</span>),<span class="hljs-string">&quot;likenum&quot;</span>:<span class="hljs-title class_">NumberInt</span>(<span class="hljs-number">666</span>),<span class="hljs-string">&quot;state&quot;</span>:<span class="hljs-string">&quot;1&quot;</span>&#125;,<br>   &#123;<span class="hljs-string">&quot;_id&quot;</span>:<span class="hljs-string">&quot;4&quot;</span>,<span class="hljs-string">&quot;articleid&quot;</span>:<span class="hljs-string">&quot;100001&quot;</span>,<span class="hljs-string">&quot;content&quot;</span>:<span class="hljs-string">&quot;专家说不能空腹吃饭，影响健康。&quot;</span>,<span class="hljs-string">&quot;userid&quot;</span>:<span class="hljs-string">&quot;1003&quot;</span>,<span class="hljs-string">&quot;nickname&quot;</span>:<span class="hljs-string">&quot;凯</span><br><span class="hljs-string">撒&quot;</span>,<span class="hljs-string">&quot;createdatetime&quot;</span>:<span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(<span class="hljs-string">&quot;2019-08-06T08:18:35.288Z&quot;</span>),<span class="hljs-string">&quot;likenum&quot;</span>:<span class="hljs-title class_">NumberInt</span>(<span class="hljs-number">2000</span>),<span class="hljs-string">&quot;state&quot;</span>:<span class="hljs-string">&quot;1&quot;</span>&#125;,<br>   &#123;<span class="hljs-string">&quot;_id&quot;</span>:<span class="hljs-string">&quot;5&quot;</span>,<span class="hljs-string">&quot;articleid&quot;</span>:<span class="hljs-string">&quot;100001&quot;</span>,<span class="hljs-string">&quot;content&quot;</span>:<span class="hljs-string">&quot;研究表明，刚烧开的水千万不能喝，因为烫</span><br><span class="hljs-string">嘴。&quot;</span>,<span class="hljs-string">&quot;userid&quot;</span>:<span class="hljs-string">&quot;1003&quot;</span>,<span class="hljs-string">&quot;nickname&quot;</span>:<span class="hljs-string">&quot;凯撒&quot;</span>,<span class="hljs-string">&quot;createdatetime&quot;</span>:<span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(<span class="hljs-string">&quot;2019-08-</span><br><span class="hljs-string">06T11:01:02.521Z&quot;</span>),<span class="hljs-string">&quot;likenum&quot;</span>:<span class="hljs-title class_">NumberInt</span>(<span class="hljs-number">3000</span>),<span class="hljs-string">&quot;state&quot;</span>:<span class="hljs-string">&quot;1&quot;</span>&#125;<br>]);<br></code></pre></td></tr></table></figure>

<p>提示：</p>
<p>插入时指定了 _id ，则主键就是该值。</p>
<p>如果某条数据插入失败，将会终止插入，但已经插入成功的数据不会回滚掉。</p>
<p>因为批量插入由于数据较多容易出现失败，因此，可以使用try catch进行异常捕捉处理，测试的时候可以不处理。如（了解）：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">try</span> &#123;<br>    db.<span class="hljs-property">comment</span>.<span class="hljs-title function_">insertMany</span>([<br>        &#123;<span class="hljs-string">&quot;_id&quot;</span>:<span class="hljs-string">&quot;1&quot;</span>,<span class="hljs-string">&quot;articleid&quot;</span>:<span class="hljs-string">&quot;100001&quot;</span>,<span class="hljs-string">&quot;content&quot;</span>:<span class="hljs-string">&quot;我们不应该把清晨浪费在手机上，健康很重要，一杯温水幸福你我</span><br><span class="hljs-string">    他。&quot;</span>,<span class="hljs-string">&quot;userid&quot;</span>:<span class="hljs-string">&quot;1002&quot;</span>,<span class="hljs-string">&quot;nickname&quot;</span>:<span class="hljs-string">&quot;相忘于江湖&quot;</span>,<span class="hljs-string">&quot;createdatetime&quot;</span>:<span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(<span class="hljs-string">&quot;2019-08-</span><br><span class="hljs-string">    05T22:08:15.522Z&quot;</span>),<span class="hljs-string">&quot;likenum&quot;</span>:<span class="hljs-title class_">NumberInt</span>(<span class="hljs-number">1000</span>),<span class="hljs-string">&quot;state&quot;</span>:<span class="hljs-string">&quot;1&quot;</span>&#125;,<br>        &#123;<span class="hljs-string">&quot;_id&quot;</span>:<span class="hljs-string">&quot;2&quot;</span>,<span class="hljs-string">&quot;articleid&quot;</span>:<span class="hljs-string">&quot;100001&quot;</span>,<span class="hljs-string">&quot;content&quot;</span>:<span class="hljs-string">&quot;我夏天空腹喝凉开水，冬天喝温开水&quot;</span>,<span class="hljs-string">&quot;userid&quot;</span>:<span class="hljs-string">&quot;1005&quot;</span>,<span class="hljs-string">&quot;nickname&quot;</span>:<span class="hljs-string">&quot;伊人憔</span><br><span class="hljs-string">    悴&quot;</span>,<span class="hljs-string">&quot;createdatetime&quot;</span>:<span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(<span class="hljs-string">&quot;2019-08-05T23:58:51.485Z&quot;</span>),<span class="hljs-string">&quot;likenum&quot;</span>:<span class="hljs-title class_">NumberInt</span>(<span class="hljs-number">888</span>),<span class="hljs-string">&quot;state&quot;</span>:<span class="hljs-string">&quot;1&quot;</span>&#125;,<br>        &#123;<span class="hljs-string">&quot;_id&quot;</span>:<span class="hljs-string">&quot;3&quot;</span>,<span class="hljs-string">&quot;articleid&quot;</span>:<span class="hljs-string">&quot;100001&quot;</span>,<span class="hljs-string">&quot;content&quot;</span>:<span class="hljs-string">&quot;我一直喝凉开水，冬天夏天都喝。&quot;</span>,<span class="hljs-string">&quot;userid&quot;</span>:<span class="hljs-string">&quot;1004&quot;</span>,<span class="hljs-string">&quot;nickname&quot;</span>:<span class="hljs-string">&quot;杰克船</span><br><span class="hljs-string">    长&quot;</span>,<span class="hljs-string">&quot;createdatetime&quot;</span>:<span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(<span class="hljs-string">&quot;2019-08-06T01:05:06.321Z&quot;</span>),<span class="hljs-string">&quot;likenum&quot;</span>:<span class="hljs-title class_">NumberInt</span>(<span class="hljs-number">666</span>),<span class="hljs-string">&quot;state&quot;</span>:<span class="hljs-string">&quot;1&quot;</span>&#125;,<br>        &#123;<span class="hljs-string">&quot;_id&quot;</span>:<span class="hljs-string">&quot;4&quot;</span>,<span class="hljs-string">&quot;articleid&quot;</span>:<span class="hljs-string">&quot;100001&quot;</span>,<span class="hljs-string">&quot;content&quot;</span>:<span class="hljs-string">&quot;专家说不能空腹吃饭，影响健康。&quot;</span>,<span class="hljs-string">&quot;userid&quot;</span>:<span class="hljs-string">&quot;1003&quot;</span>,<span class="hljs-string">&quot;nickname&quot;</span>:<span class="hljs-string">&quot;凯</span><br><span class="hljs-string">    撒&quot;</span>,<span class="hljs-string">&quot;createdatetime&quot;</span>:<span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(<span class="hljs-string">&quot;2019-08-06T08:18:35.288Z&quot;</span>),<span class="hljs-string">&quot;likenum&quot;</span>:<span class="hljs-title class_">NumberInt</span>(<span class="hljs-number">2000</span>),<span class="hljs-string">&quot;state&quot;</span>:<span class="hljs-string">&quot;1&quot;</span>&#125;,<br>        &#123;<span class="hljs-string">&quot;_id&quot;</span>:<span class="hljs-string">&quot;5&quot;</span>,<span class="hljs-string">&quot;articleid&quot;</span>:<span class="hljs-string">&quot;100001&quot;</span>,<span class="hljs-string">&quot;content&quot;</span>:<span class="hljs-string">&quot;研究表明，刚烧开的水千万不能喝，因为烫</span><br><span class="hljs-string">    嘴。&quot;</span>,<span class="hljs-string">&quot;userid&quot;</span>:<span class="hljs-string">&quot;1003&quot;</span>,<span class="hljs-string">&quot;nickname&quot;</span>:<span class="hljs-string">&quot;凯撒&quot;</span>,<span class="hljs-string">&quot;createdatetime&quot;</span>:<span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(<span class="hljs-string">&quot;2019-08-</span><br><span class="hljs-string">    06T11:01:02.521Z&quot;</span>),<span class="hljs-string">&quot;likenum&quot;</span>:<span class="hljs-title class_">NumberInt</span>(<span class="hljs-number">3000</span>),<span class="hljs-string">&quot;state&quot;</span>:<span class="hljs-string">&quot;1&quot;</span>&#125;<br>    ]);<br>    &#125;<br>    <span class="hljs-keyword">catch</span> (e) &#123;<br>        print (e);<br>    &#125;<br></code></pre></td></tr></table></figure>

<h3 id="3-4-2-文档的基本查询"><a href="#3-4-2-文档的基本查询" class="headerlink" title="3.4.2 文档的基本查询"></a>3.4.2 文档的基本查询</h3><p> 查询数据的语法格式如下：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs js">db.<span class="hljs-property">collection</span>.<span class="hljs-title function_">find</span>(&lt;query&gt;, [projection])<br></code></pre></td></tr></table></figure>

<p>参数：</p>
<table>
<thead>
<tr>
<th><strong>Parameter</strong></th>
<th><strong>Type</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody><tr>
<td>query</td>
<td>document</td>
<td>可选。使用查询运算符指定选择筛选器。若要返回集合中的所有文档，请省略此参数或传递空文档( {} )。</td>
</tr>
<tr>
<td>projection</td>
<td>document</td>
<td>可选。指定要在与查询筛选器匹配的文档中返回的字段（投影）。若要返回匹配文档中的所有字段，</td>
</tr>
</tbody></table>
<p>【示例】</p>
<p>（1）查询所有</p>
<p>如果我们要查询comment集合的所有文档，我们输入以下命令</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs js">db.<span class="hljs-property">comment</span>.<span class="hljs-title function_">find</span>()<br>或<br>db.<span class="hljs-property">comment</span>.<span class="hljs-title function_">find</span>(&#123;&#125;)<br></code></pre></td></tr></table></figure>

<p>这里你会发现每条文档会有一个叫_id的字段，这个相当于我们原来关系数据库中表的主键，当你在插入文档记录时没有指定该字段，</p>
<p>MongoDB会自动创建，其类型是ObjectID类型。 </p>
<p>如果我们在插入文档记录时指定该字段也可以，其类型可以是ObjectID类型，也可以是MongoDB支持的任意类型。</p>
<p>如果我想按一定条件来查询，比如我想查询userid为1003的记录，怎么办？很简单！只 要在fifind()中添加参数即可，参数也是json格式，如下：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs js">db.<span class="hljs-property">comment</span>.<span class="hljs-title function_">find</span>(&#123;<span class="hljs-attr">userid</span>:<span class="hljs-string">&#x27;1003&#x27;</span>&#125;)<br></code></pre></td></tr></table></figure>

<p>如果你只需要返回符合条件的第一条数据，我们可以使用fifindOne命令来实现，语法和fifind一样。</p>
<p>如：查询用户编号是1003的记录，但只最多返回符合条件的第一条记录：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs js">db.<span class="hljs-property">comment</span>.<span class="hljs-title function_">findOne</span>(&#123;<span class="hljs-attr">userid</span>:<span class="hljs-string">&#x27;1003&#x27;</span>&#125;)<br></code></pre></td></tr></table></figure>

<p>（2）投影查询（Projection Query）：</p>
<p>如果要查询结果返回部分字段，则需要使用投影查询（不显示所有字段，只显示指定的字段）。</p>
<p>如：查询结果只显示 _id、userid、nickname : </p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs js">&gt;db.<span class="hljs-property">comment</span>.<span class="hljs-title function_">find</span>(<span class="hljs-params">&#123;userid:<span class="hljs-string">&quot;1003&quot;</span>&#125;,&#123;userid:<span class="hljs-number">1</span>,nickname:<span class="hljs-number">1</span>&#125;</span>)<br>&#123; <span class="hljs-string">&quot;_id&quot;</span> : <span class="hljs-string">&quot;4&quot;</span>, <span class="hljs-string">&quot;userid&quot;</span> : <span class="hljs-string">&quot;1003&quot;</span>, <span class="hljs-string">&quot;nickname&quot;</span> : <span class="hljs-string">&quot;凯撒&quot;</span> &#125;<br>&#123; <span class="hljs-string">&quot;_id&quot;</span> : <span class="hljs-string">&quot;5&quot;</span>, <span class="hljs-string">&quot;userid&quot;</span> : <span class="hljs-string">&quot;1003&quot;</span>, <span class="hljs-string">&quot;nickname&quot;</span> : <span class="hljs-string">&quot;凯撒&quot;</span> &#125;<br></code></pre></td></tr></table></figure>

<p>默认 _id 会显示。</p>
<p>如：查询结果只显示 、userid、nickname ，不显示 _id ：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript">&gt;db.<span class="hljs-property">comment</span>.<span class="hljs-title function_">find</span>(<span class="hljs-params">&#123;userid:<span class="hljs-string">&quot;1003&quot;</span>&#125;,&#123;userid:<span class="hljs-number">1</span>,nickname:<span class="hljs-number">1</span>,_id:<span class="hljs-number">0</span>&#125;</span>)<br>&#123; <span class="hljs-string">&quot;userid&quot;</span> : <span class="hljs-string">&quot;1003&quot;</span>, <span class="hljs-string">&quot;nickname&quot;</span> : <span class="hljs-string">&quot;凯撒&quot;</span> &#125;<br>&#123; <span class="hljs-string">&quot;userid&quot;</span> : <span class="hljs-string">&quot;1003&quot;</span>, <span class="hljs-string">&quot;nickname&quot;</span> : <span class="hljs-string">&quot;凯撒&quot;</span> &#125;<br></code></pre></td></tr></table></figure>

<p>再例如：查询所有数据，但只显示 _id、userid、nickname :</p>
<figure class="highlight dust"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs dust"><span class="language-xml">&gt;db.comment.find(</span><span class="hljs-template-variable">&#123;&#125;</span><span class="language-xml">,</span><span class="hljs-template-variable">&#123;userid:1,nickname:1&#125;</span><span class="language-xml">)</span><br></code></pre></td></tr></table></figure>

<h3 id="3-4-3-文档的更新"><a href="#3-4-3-文档的更新" class="headerlink" title="3.4.3 文档的更新"></a>3.4.3 文档的更新</h3><p>更新文档的语法：</p>
<figure class="highlight vim"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs vim">db.collection.<span class="hljs-keyword">update</span>(query, <span class="hljs-keyword">update</span>, <span class="hljs-keyword">options</span>)<br>//或<br>db.collection.<span class="hljs-keyword">update</span>(<br>    <span class="hljs-symbol">&lt;query&gt;</span>,<br>    <span class="hljs-symbol">&lt;update&gt;</span>,<br>    &#123;<br>        upsert: <span class="hljs-symbol">&lt;boolean&gt;</span>,<br>        multi: <span class="hljs-symbol">&lt;boolean&gt;</span>,<br>        writeConcern: <span class="hljs-symbol">&lt;document&gt;</span>,<br>        collation: <span class="hljs-symbol">&lt;document&gt;</span>,<br>        arrayFilters: [ <span class="hljs-symbol">&lt;filterdocument1&gt;</span>, ... ],<br>        hint: &lt;document|<span class="hljs-built_in">string</span>&gt; // Available starting in MongoDB <span class="hljs-number">4.2</span><br>	&#125;<br>)<br></code></pre></td></tr></table></figure>

<p>参数：</p>
<table>
<thead>
<tr>
<th><strong>Parameter</strong></th>
<th><strong>Type</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody><tr>
<td>query</td>
<td>document</td>
<td>更新的选择条件。可以使用与find（）方法中相同的查询选择器，类似sql update查询内where后面的。</td>
</tr>
<tr>
<td>update</td>
<td>document<br>or<br>pipeline</td>
<td>要应用的修改。该值可以是：包含更新运算符表达式的文档，或仅包含：对的替换文档，或在MongoDB 4.2中启动聚合管道</td>
</tr>
<tr>
<td>upsert</td>
<td>boolean</td>
<td>可选。如果设置为true，则在没有与查询条件匹配的文档时创建新文档。默认值为false，如果找不到匹配项，则不会插入新文档。</td>
</tr>
<tr>
<td>multi</td>
<td>boolean</td>
<td>可选。如果设置为true，则更新符合查询条件的多个文档。如果设置为false，则更新一个文档。默认值为false。</td>
</tr>
<tr>
<td>writeConcern</td>
<td>document</td>
<td>可选。表示写问题的文档。抛出异常的级别。</td>
</tr>
<tr>
<td>collation</td>
<td>document</td>
<td>可选。<br>指定要用于操作的校对规则。<br>校对规则允许用户为字符串比较指定特定于语言的规则，例如字母大小写和重音标记的规则。<br>校对规则选项具有以下语法：<br>校对规则：{<br>区域设置：，<br>caseLevel:，<br>caseFirst:，<br>强度：，<br>numericordering:，<br>替代：，<br>最大变量：，<br>向后：<br>}<br>指定校对规则时，区域设置字段是必需的；所有其他校对规则字段都是可选的。有关字段的说明，请参阅校对规则文档。<br>如果未指定校对规则，但集合具有默认校对规则（请参见db.createCollection（）），则该操作将使用为集合指定的校对规则。<br>如果没有为集合或操作指定校对规则，MongoDB将使用以前版本中使用的简单二进制比较进行字符串比较。不能为一个操作指定多个校对规则。例如，不能为每个字段指定不同的校对规则，或者如果使用排序执行查找，则不能将一个校对规则用于查找，另一个校对规则用于排序。<br>3.4版新增。</td>
</tr>
<tr>
<td>arrayFilters</td>
<td>array</td>
<td>可选。一个筛选文档数组，用于确定要为数组字段上的更新操作修改哪些数组元素。</td>
</tr>
<tr>
<td>hint</td>
<td>Document<br>or string</td>
<td>可选。指定用于支持查询谓词的索引的文档或字符串。该选项可以采用索引规范文档或索引名称字符串。如果指定的索引不存在，则说明操作错误。例如，请参阅版本4中的“为更新操作指定提示。</td>
</tr>
</tbody></table>
<blockquote>
<p>tip:主要关注前四个参数即可。</p>
</blockquote>
<p>例如</p>
<p>（1）覆盖的修改</p>
<p>如果想修改_id为1的记录，点赞量为1001，输入以下语句：</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css">db<span class="hljs-selector-class">.comment</span><span class="hljs-selector-class">.update</span>(&#123;_id:<span class="hljs-string">&quot;1&quot;</span>&#125;,&#123;likenum:<span class="hljs-built_in">NumberInt</span>(<span class="hljs-number">1001</span>)&#125;)<br></code></pre></td></tr></table></figure>

<p>执行后，这条文档除了likenum字段其它字段都不见了</p>
<p>（2） 局部修改</p>
<p>修改_id为2的记录，浏览量为889。使用修改器$set来实现：</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">db<span class="hljs-selector-class">.comment</span><span class="hljs-selector-class">.update</span>(&#123;_id:<span class="hljs-string">&quot;2&quot;</span>&#125;,&#123;<span class="hljs-variable">$set</span>:&#123;likenum:<span class="hljs-built_in">NumberInt</span>(<span class="hljs-number">889</span>)&#125;&#125;)<br></code></pre></td></tr></table></figure>

<p>（3）批量修改</p>
<p>更新所有用户为1003 的用户的昵称为凯撒大帝。</p>
<figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-comment">//默认只修改第一条数据</span><br>db.comment.<span class="hljs-title function_ invoke__">update</span>(&#123;<span class="hljs-attr">userid</span>:<span class="hljs-string">&quot;1003&quot;</span>&#125;,&#123;<span class="hljs-variable">$set</span>:&#123;<span class="hljs-attr">nickname</span>:<span class="hljs-string">&quot;凯撒2&quot;</span>&#125;&#125;)<br><span class="hljs-comment">//修改所有符合条件的数据</span><br>db.comment.<span class="hljs-title function_ invoke__">update</span>(&#123;<span class="hljs-attr">userid</span>:<span class="hljs-string">&quot;1003&quot;</span>&#125;,&#123;<span class="hljs-variable">$set</span>:&#123;<span class="hljs-attr">nickname</span>:<span class="hljs-string">&quot;凯撒大帝&quot;</span>&#125;&#125;,&#123;<span class="hljs-attr">multi</span>:<span class="hljs-literal">true</span>&#125;)<br></code></pre></td></tr></table></figure>

<blockquote>
<p>tip: 如果不加后面的参数，则只更新符合条件的第一条记录</p>
</blockquote>
<p>（4）列值增长的修改</p>
<p>对某列值在原有值的基础上进行增加或减少，可以使用$inc 运算符来实现。</p>
<p>对3号数据的点赞数，每次递增1</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">db<span class="hljs-selector-class">.comment</span><span class="hljs-selector-class">.update</span>(&#123;_id:<span class="hljs-string">&quot;3&quot;</span>&#125;,&#123;<span class="hljs-variable">$inc</span>:&#123;likenum:<span class="hljs-built_in">NumberInt</span>(<span class="hljs-number">1</span>)&#125;&#125;)<br></code></pre></td></tr></table></figure>

<h3 id="3-4-4-文档的删除"><a href="#3-4-4-文档的删除" class="headerlink" title="3.4.4 文档的删除"></a>3.4.4 文档的删除</h3><p>删除文档的语法结构：</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs routeros">db.集合名称.<span class="hljs-built_in">remove</span>(条件)<br></code></pre></td></tr></table></figure>

<p>全部删除，<strong>慎用</strong></p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs routeros">db.comment.<span class="hljs-built_in">remove</span>(&#123;&#125;)<br></code></pre></td></tr></table></figure>

<p>删除_id&#x3D;1的记录</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs routeros">db.comment.<span class="hljs-built_in">remove</span>(&#123;_id:<span class="hljs-string">&quot;1&quot;</span>&#125;)<br></code></pre></td></tr></table></figure>

<h2 id="3-5-文档的分页查询"><a href="#3-5-文档的分页查询" class="headerlink" title="3.5 文档的分页查询"></a>3.5 文档的分页查询</h2><h3 id="3-5-1-统计查询"><a href="#3-5-1-统计查询" class="headerlink" title="3.5.1 统计查询"></a>3.5.1 统计查询</h3><p>统计查询使用count()方法，语法如下：</p>
<figure class="highlight stata"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stata"><span class="hljs-keyword">db</span>.collection.<span class="hljs-keyword">count</span>(<span class="hljs-keyword">query</span>, options)<br></code></pre></td></tr></table></figure>

<p>参数：</p>
<table>
<thead>
<tr>
<th><strong>Parameter</strong></th>
<th><strong>Type</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody><tr>
<td>query</td>
<td>document</td>
<td>查询选择条件。</td>
</tr>
<tr>
<td>projection</td>
<td>document</td>
<td>可选。用于修改计数的额外选项。</td>
</tr>
</tbody></table>
<p>例如</p>
<p>（1）统计所有记录数</p>
<p>统计comment集合的所有的记录数：</p>
<figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs pgsql">db.<span class="hljs-keyword">comment</span>.count()<br></code></pre></td></tr></table></figure>

<p>（2）按条件统计记录数</p>
<p>例如：统计userid为1003的记录条数</p>
<figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs pgsql">db.<span class="hljs-keyword">comment</span>.count(&#123;userid:&quot;1003&quot;&#125;)<br></code></pre></td></tr></table></figure>

<blockquote>
<p>tip: 默认情况下count() 方法返回符合条件的全部记录条数。</p>
</blockquote>
<h3 id="3-5-2-分页列表查询"><a href="#3-5-2-分页列表查询" class="headerlink" title="3.5.2 分页列表查询"></a>3.5.2 分页列表查询</h3><p>可以使用limit()方法来读取指定数量的数据，使用skip()方法来跳过指定数量的数据。</p>
<p>基本语法如下所示：</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">&gt;db<span class="hljs-selector-class">.COLLECTION_NAME</span><span class="hljs-selector-class">.find</span>()<span class="hljs-selector-class">.limit</span>(NUMBER)<span class="hljs-selector-class">.skip</span>(NUMBER)<br></code></pre></td></tr></table></figure>

<p>如果想返回指定条数的记录，可以在find方法后调用limit来返回结果(TopN)，默认值20，例如：</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">db<span class="hljs-selector-class">.comment</span><span class="hljs-selector-class">.find</span>()<span class="hljs-selector-class">.limit</span>(<span class="hljs-number">3</span>)<br></code></pre></td></tr></table></figure>

<p>skip方法同样接受一个数字参数作为跳过的记录条数。（前N个不要）,默认值是0</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">db<span class="hljs-selector-class">.comment</span><span class="hljs-selector-class">.find</span>()<span class="hljs-selector-class">.skip</span>(<span class="hljs-number">3</span>)<br></code></pre></td></tr></table></figure>

<p>分页查询：需求：每页2个，第二页开始：跳过前两条数据，接着值显示3和4条数据</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs stylus"><span class="hljs-comment">//第一页</span><br>db<span class="hljs-selector-class">.comment</span><span class="hljs-selector-class">.find</span>()<span class="hljs-selector-class">.skip</span>(<span class="hljs-number">0</span>)<span class="hljs-selector-class">.limit</span>(<span class="hljs-number">2</span>)<br><span class="hljs-comment">//第二页</span><br>db<span class="hljs-selector-class">.comment</span><span class="hljs-selector-class">.find</span>()<span class="hljs-selector-class">.skip</span>(<span class="hljs-number">2</span>)<span class="hljs-selector-class">.limit</span>(<span class="hljs-number">2</span>)<br><span class="hljs-comment">//第三页</span><br>db<span class="hljs-selector-class">.comment</span><span class="hljs-selector-class">.find</span>()<span class="hljs-selector-class">.skip</span>(<span class="hljs-number">4</span>)<span class="hljs-selector-class">.limit</span>(<span class="hljs-number">2</span>)<br></code></pre></td></tr></table></figure>

<h3 id="3-5-3-排序查询"><a href="#3-5-3-排序查询" class="headerlink" title="3.5.3 排序查询"></a>3.5.3 排序查询</h3><p>sort() 方法对数据进行排序，sort() 方法可以通过参数指定排序的字段，并使用 1 和 -1 来指定排序的方式，其中 1 为升序排列，而 -1 是用<br>于降序排列。<br>语法如下所示：</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs stylus">db<span class="hljs-selector-class">.COLLECTION_NAME</span><span class="hljs-selector-class">.find</span>()<span class="hljs-selector-class">.sort</span>(&#123;KEY:<span class="hljs-number">1</span>&#125;)<br>或<br>db.集合名称<span class="hljs-selector-class">.find</span>()<span class="hljs-selector-class">.sort</span>(排序方式)<br></code></pre></td></tr></table></figure>

<p>对userid降序排列，并对访问量进行升序排列</p>
<figure class="highlight sqf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sqf">db.<span class="hljs-built_in">comment</span>.<span class="hljs-built_in">find</span>().<span class="hljs-built_in">sort</span>(&#123;userid:-<span class="hljs-number">1</span>,likenum:<span class="hljs-number">1</span>&#125;)<br></code></pre></td></tr></table></figure>

<blockquote>
<p>tip：skip(), limilt(), sort()三个放在一起执行的时候，执行的顺序是先 sort(), 然后是 skip()，最后是显示的 limit()，和命令编写顺序无关。</p>
</blockquote>
<h2 id="3-6-文档的更多查询"><a href="#3-6-文档的更多查询" class="headerlink" title="3.6 文档的更多查询"></a>3.6 文档的更多查询</h2><h3 id="3-6-1-正则的复杂条件查询"><a href="#3-6-1-正则的复杂条件查询" class="headerlink" title="3.6.1 正则的复杂条件查询"></a>3.6.1 正则的复杂条件查询</h3><p>MongoDB的模糊查询是通过正则表达式的方式实现的。格式为：</p>
<figure class="highlight arcade"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs arcade">db.collection.<span class="hljs-built_in">find</span>(&#123;<span class="hljs-attr">field</span>:<span class="hljs-regexp">/正则表达式/</span>&#125;)<br>或<br>db.集合.<span class="hljs-built_in">find</span>(&#123;字段:<span class="hljs-regexp">/正则表达式/</span>&#125;)<br></code></pre></td></tr></table></figure>

<blockquote>
<p>tip: 正则表达式是js的语法，直接量的写法。</p>
</blockquote>
<p>要查询评论内容包含“开水”的所有文档：</p>
<figure class="highlight arcade"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs arcade">db.comment.<span class="hljs-built_in">find</span>(&#123;<span class="hljs-attr">content</span>:<span class="hljs-regexp">/开水/</span>&#125;)<br></code></pre></td></tr></table></figure>

<p>要查询评论的内容中以“专家”开头的：</p>
<figure class="highlight arcade"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs arcade">db.comment.<span class="hljs-built_in">find</span>(&#123;<span class="hljs-attr">content</span>:<span class="hljs-regexp">/^专家/</span>&#125;)<br></code></pre></td></tr></table></figure>

<h3 id="3-6-2-比较查询"><a href="#3-6-2-比较查询" class="headerlink" title="3.6.2 比较查询"></a>3.6.2 比较查询</h3><p>&lt;, &lt;&#x3D;, &gt;, &gt;&#x3D; 这个操作符也是很常用的，格式如下:</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs awk">db.集合名称.find(&#123; <span class="hljs-string">&quot;field&quot;</span> : &#123; <span class="hljs-variable">$gt</span>: value &#125;&#125;) <span class="hljs-regexp">//</span> 大于: field &gt; value<br>db.集合名称.find(&#123; <span class="hljs-string">&quot;field&quot;</span> : &#123; <span class="hljs-variable">$lt</span>: value &#125;&#125;) <span class="hljs-regexp">//</span> 小于: field &lt; value<br>db.集合名称.find(&#123; <span class="hljs-string">&quot;field&quot;</span> : &#123; <span class="hljs-variable">$gte</span>: value &#125;&#125;) <span class="hljs-regexp">//</span> 大于等于: field &gt;= value<br>db.集合名称.find(&#123; <span class="hljs-string">&quot;field&quot;</span> : &#123; <span class="hljs-variable">$lte</span>: value &#125;&#125;) <span class="hljs-regexp">//</span> 小于等于: field &lt;= value<br>db.集合名称.find(&#123; <span class="hljs-string">&quot;field&quot;</span> : &#123; <span class="hljs-variable">$ne</span>: value &#125;&#125;) <span class="hljs-regexp">//</span> 不等于: field != value<br></code></pre></td></tr></table></figure>

<p>示例：查询评论点赞数量大于700的记录</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">db<span class="hljs-selector-class">.comment</span><span class="hljs-selector-class">.find</span>(&#123;likenum:&#123;<span class="hljs-variable">$gt</span>:<span class="hljs-built_in">NumberInt</span>(<span class="hljs-number">700</span>)&#125;&#125;)<br></code></pre></td></tr></table></figure>

<h3 id="3-6-3-包含查询"><a href="#3-6-3-包含查询" class="headerlink" title="3.6.3 包含查询"></a>3.6.3 包含查询</h3><p>包含使用$in操作符。 示例：查询评论的集合中userid字段包含1003或1004的文档</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">db<span class="hljs-selector-class">.comment</span><span class="hljs-selector-class">.find</span>(&#123;userid:&#123;<span class="hljs-variable">$in</span>:<span class="hljs-selector-attr">[<span class="hljs-string">&quot;1003&quot;</span>,<span class="hljs-string">&quot;1004&quot;</span>]</span>&#125;&#125;)<br></code></pre></td></tr></table></figure>

<p>不包含使用$nin操作符。 示例：查询评论集合中userid字段不包含1003和1004的文档</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">db<span class="hljs-selector-class">.comment</span><span class="hljs-selector-class">.find</span>(&#123;userid:&#123;<span class="hljs-variable">$nin</span>:<span class="hljs-selector-attr">[<span class="hljs-string">&quot;1003&quot;</span>,<span class="hljs-string">&quot;1004&quot;</span>]</span>&#125;&#125;)<br></code></pre></td></tr></table></figure>

<h3 id="3-6-4-条件连接查询"><a href="#3-6-4-条件连接查询" class="headerlink" title="3.6.4 条件连接查询"></a>3.6.4 条件连接查询</h3><p>如果需要查询同时满足两个以上条件，需要使用$and操作符将条件进行关联。（相 当于SQL的and） 格式为：</p>
<figure class="highlight dust"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs dust"><span class="language-xml">$and:[ </span><span class="hljs-template-variable">&#123; &#125;</span><span class="language-xml">,</span><span class="hljs-template-variable">&#123; &#125;</span><span class="language-xml">,</span><span class="hljs-template-variable">&#123; &#125;</span><span class="language-xml"> ]</span><br></code></pre></td></tr></table></figure>

<p>查询评论集合中likenum大于等于700 并且小于2000的文档：</p>
<figure class="highlight elixir"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs elixir">db.comment.find(&#123;<span class="hljs-variable">$and</span><span class="hljs-symbol">:</span>[&#123;<span class="hljs-symbol">likenum:</span>&#123;<span class="hljs-variable">$gte</span><span class="hljs-symbol">:NumberInt</span>(<span class="hljs-number">700</span>)&#125;&#125;,&#123;<span class="hljs-symbol">likenum:</span>&#123;<span class="hljs-variable">$lt</span><span class="hljs-symbol">:NumberInt</span>(<span class="hljs-number">2000</span>)&#125;&#125;]&#125;)<br></code></pre></td></tr></table></figure>

<p>如果两个以上条件之间是或者的关系，我们使用 操作符进行关联，与前面 and的使用方式相同 格式为：</p>
<figure class="highlight dust"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs dust"><span class="language-xml">$or:[ </span><span class="hljs-template-variable">&#123; &#125;</span><span class="language-xml">,</span><span class="hljs-template-variable">&#123; &#125;</span><span class="language-xml">,</span><span class="hljs-template-variable">&#123; &#125;</span><span class="language-xml"> ]</span><br></code></pre></td></tr></table></figure>

<p>查询评论集合中userid为1003，或者点赞数小于1000的文档记录</p>
<figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs php">db.comment.<span class="hljs-title function_ invoke__">find</span>(&#123;<span class="hljs-variable">$or</span>:[ &#123;<span class="hljs-attr">userid</span>:<span class="hljs-string">&quot;1003&quot;</span>&#125; ,&#123;<span class="hljs-attr">likenum</span>:&#123;<span class="hljs-variable">$lt</span>:<span class="hljs-number">1000</span>&#125; &#125;]&#125;)<br></code></pre></td></tr></table></figure>

<h2 id="3-7-常用命令小结"><a href="#3-7-常用命令小结" class="headerlink" title="3.7 常用命令小结"></a>3.7 常用命令小结</h2><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs routeros">选择切换数据库：use articledb<br>插入数据：db.comment.insert(&#123;bson数据&#125;)<br>查询所有数据：db.comment.<span class="hljs-built_in">find</span>();<br>条件查询数据：db.comment.<span class="hljs-built_in">find</span>(&#123;条件&#125;)<br>查询符合条件的第一条记录：db.comment.findOne(&#123;条件&#125;)<br>查询符合条件的前几条记录：db.comment.<span class="hljs-built_in">find</span>(&#123;条件&#125;).limit(条数)<br>查询符合条件的跳过的记录：db.comment.<span class="hljs-built_in">find</span>(&#123;条件&#125;).skip(条数)<br>修改数据：db.comment.update(&#123;条件&#125;,&#123;修改后的数据&#125;) 或db.comment.update(&#123;条件&#125;,&#123;<span class="hljs-variable">$set</span>:&#123;要修改部分的字段:数据&#125;)<br>修改数据并自增某字段值：db.comment.update(&#123;条件&#125;,&#123;<span class="hljs-variable">$inc</span>:&#123;自增的字段:步进值&#125;&#125;)<br>删除数据：db.comment.<span class="hljs-built_in">remove</span>(&#123;条件&#125;)<br>统计查询：db.comment.count(&#123;条件&#125;)<br>模糊查询：db.comment.<span class="hljs-built_in">find</span>(&#123;字段名:/正则表达式/&#125;)<br>条件比较运算：db.comment.<span class="hljs-built_in">find</span>(&#123;字段名:&#123;<span class="hljs-variable">$gt</span>:值&#125;&#125;)<br>包含查询：db.comment.<span class="hljs-built_in">find</span>(&#123;字段名:&#123;<span class="hljs-variable">$in</span>:[值1，值2]&#125;&#125;)或db.comment.<span class="hljs-built_in">find</span>(&#123;字段名:&#123;<span class="hljs-variable">$nin</span>:[值1，值2]&#125;&#125;)<br>条件连接查询：db.comment.<span class="hljs-built_in">find</span>(&#123;<span class="hljs-variable">$and</span>:[&#123;条件1&#125;,&#123;条件2&#125;]&#125;)或db.comment.<span class="hljs-built_in">find</span>(&#123;<span class="hljs-variable">$or</span>:[&#123;条件1&#125;,&#123;条件2&#125;]&#125;)<br></code></pre></td></tr></table></figure>

<h1 id="4-索引-Index"><a href="#4-索引-Index" class="headerlink" title="4 索引-Index"></a>4 索引-Index</h1><h2 id="4-1-概述"><a href="#4-1-概述" class="headerlink" title="4.1 概述"></a>4.1 概述</h2><p>MongoDB索引使用B树数据结构（确切的说是B-Tree，MySQL是B+Tree）</p>
<h2 id="4-2-索引类型"><a href="#4-2-索引类型" class="headerlink" title="4.2 索引类型"></a>4.2 索引类型</h2><ul>
<li>单字段索引</li>
<li>复合索引</li>
<li>其他索引</li>
</ul>
<h2 id="4-3-索引的管理操作"><a href="#4-3-索引的管理操作" class="headerlink" title="4.3 索引的管理操作"></a>4.3 索引的管理操作</h2><h3 id="4-3-1-索引的查看"><a href="#4-3-1-索引的查看" class="headerlink" title="4.3.1 索引的查看"></a>4.3.1 索引的查看</h3><p>返回一个集合中的所有索引的数组。</p>
<p>语法</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">db<span class="hljs-selector-class">.collection</span><span class="hljs-selector-class">.getIndexes</span>()<br></code></pre></td></tr></table></figure>

<p>查看comment集合中所有的索引情况</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">db<span class="hljs-selector-class">.comment</span><span class="hljs-selector-class">.getIndexes</span>()<br></code></pre></td></tr></table></figure>

<blockquote>
<p>结果中显示的是默认_id 索引。</p>
</blockquote>
<h3 id="4-3-2-索引创建"><a href="#4-3-2-索引创建" class="headerlink" title="4.3.2 索引创建"></a>4.3.2 索引创建</h3><p>在集合上创建索引。</p>
<p>语法</p>
<figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs reasonml">db.collection.create<span class="hljs-constructor">Index(<span class="hljs-params">keys</span>, <span class="hljs-params">options</span>)</span><br></code></pre></td></tr></table></figure>

<p>参数：</p>
<table>
<thead>
<tr>
<th><strong>Parameter</strong></th>
<th><strong>Type</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody><tr>
<td>keys</td>
<td>document</td>
<td>包含字段和值对的文档，其中字段是索引键，值描述该字段的索引类型。对于字段上的升序索引，请<br>指定值1；对于降序索引，请指定值-1。比如： {字段:1或-1} ，其中1 为指定按升序创建索引，如果你<br>想按降序来创建索引指定为 -1 即可。另外，MongoDB支持几种不同的索引类型，包括文本、地理空<br>间和哈希索引。</td>
</tr>
<tr>
<td>options</td>
<td>document</td>
<td>可选。包含一组控制索引创建的选项的文档。有关详细信息，请参见选项详情列表。</td>
</tr>
</tbody></table>
<p>例子</p>
<p>（1）单字段索引示例：对userid 字段建立索引：</p>
<figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs reasonml">db.comment.create<span class="hljs-constructor">Index(&#123;<span class="hljs-params">userid</span>:1&#125;)</span><br></code></pre></td></tr></table></figure>

<p>（2）复合索引：对userid 和nickname 同时建立复合（Compound）索引：</p>
<figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs reasonml">db.comment.create<span class="hljs-constructor">Index(&#123;<span class="hljs-params">userid</span>:1,<span class="hljs-params">nickname</span>:-1&#125;)</span><br></code></pre></td></tr></table></figure>

<h3 id="4-3-3-索引的移除"><a href="#4-3-3-索引的移除" class="headerlink" title="4.3.3 索引的移除"></a>4.3.3 索引的移除</h3><p>一、指定索引的移除</p>
<p>语法：</p>
<figure class="highlight sas"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sas">db.collection.<span class="hljs-keyword">drop</span><span class="hljs-meta">Index</span>(<span class="hljs-keyword">index</span>)<br></code></pre></td></tr></table></figure>

<p>参数：</p>
<table>
<thead>
<tr>
<th><strong>Parameter</strong></th>
<th><strong>Type</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody><tr>
<td>index</td>
<td>string or<br>document</td>
<td>指定要删除的索引。可以通过索引名称或索引规范文档指定索引。若要删除文本索引，请指定<br>索引名称。</td>
</tr>
</tbody></table>
<p>例子：</p>
<p>删除comment 集合中userid 字段上的升序索引：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript">&gt; db.<span class="hljs-property">comment</span>.<span class="hljs-title function_">dropIndex</span>(<span class="hljs-params">&#123;userid:<span class="hljs-number">1</span>&#125;</span>)<br>&#123; <span class="hljs-string">&quot;nIndexesWas&quot;</span> : <span class="hljs-number">3</span>, <span class="hljs-string">&quot;ok&quot;</span> : <span class="hljs-number">1</span> &#125;<br></code></pre></td></tr></table></figure>

<p>二、所有索引的移除</p>
<p>语法：</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">db<span class="hljs-selector-class">.collection</span><span class="hljs-selector-class">.dropIndexes</span>()<br></code></pre></td></tr></table></figure>

<p>删除spit 集合中所有索引:</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">db<span class="hljs-selector-class">.comment</span><span class="hljs-selector-class">.dropIndexes</span>()<br></code></pre></td></tr></table></figure>

<h2 id="4-4-索引的使用"><a href="#4-4-索引的使用" class="headerlink" title="4.4 索引的使用"></a>4.4 索引的使用</h2><h3 id="4-4-1-执行计划"><a href="#4-4-1-执行计划" class="headerlink" title="4.4.1 执行计划"></a>4.4.1 执行计划</h3><p>建立的索引是否有效，效果如何，都需要通过执行计划查看</p>
<p>语法</p>
<figure class="highlight gradle"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs gradle">db.collection.<span class="hljs-keyword">find</span>(query,<span class="hljs-keyword">options</span>).explain(<span class="hljs-keyword">options</span>)<br></code></pre></td></tr></table></figure>

<p>例子：查看根据userid查询数据的情况</p>
<figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs php">&gt;db.comment.<span class="hljs-title function_ invoke__">find</span>(&#123;<span class="hljs-attr">userid</span>:<span class="hljs-string">&quot;1003&quot;</span>&#125;).<span class="hljs-title function_ invoke__">explain</span>()<br><br>&#123;<br>    <span class="hljs-string">&quot;queryPlanner&quot;</span> : &#123;<br>        <span class="hljs-string">&quot;plannerVersion&quot;</span> : <span class="hljs-number">1</span>,<br>        <span class="hljs-string">&quot;namespace&quot;</span> : <span class="hljs-string">&quot;articledb.comment&quot;</span>,<br>        <span class="hljs-string">&quot;indexFilterSet&quot;</span> : <span class="hljs-literal">false</span>,<br>        <span class="hljs-string">&quot;parsedQuery&quot;</span> : &#123;<br>            <span class="hljs-string">&quot;userid&quot;</span> : &#123;<br>             <span class="hljs-string">&quot;<span class="hljs-subst">$eq</span>&quot;</span> : <span class="hljs-string">&quot;1003&quot;</span><br>            &#125;<br>        &#125;,<br>        <span class="hljs-string">&quot;winningPlan&quot;</span> : &#123;<br>            <span class="hljs-string">&quot;stage&quot;</span> : <span class="hljs-string">&quot;COLLSCAN&quot;</span>, <span class="hljs-comment">//全局扫描就是没有走索引</span><br>            <span class="hljs-string">&quot;filter&quot;</span> : &#123;<br>                <span class="hljs-string">&quot;userid&quot;</span> : &#123;<br>                	<span class="hljs-string">&quot;<span class="hljs-subst">$eq</span>&quot;</span> : <span class="hljs-string">&quot;1003&quot;</span><br>            	&#125;<br>            &#125;,<br>            <span class="hljs-string">&quot;direction&quot;</span> : <span class="hljs-string">&quot;forward&quot;</span><br>        &#125;,<br>        <span class="hljs-string">&quot;rejectedPlans&quot;</span> : [ ]<br>    &#125;,<br>    <span class="hljs-string">&quot;serverInfo&quot;</span> : &#123;<br>        <span class="hljs-string">&quot;host&quot;</span> : <span class="hljs-string">&quot;9ef3740277ad&quot;</span>,<br>        <span class="hljs-string">&quot;port&quot;</span> : <span class="hljs-number">27017</span>,<br>        <span class="hljs-string">&quot;version&quot;</span> : <span class="hljs-string">&quot;4.0.10&quot;</span>,<br>        <span class="hljs-string">&quot;gitVersion&quot;</span> : <span class="hljs-string">&quot;c389e7f69f637f7a1ac3cc9fae843b635f20b766&quot;</span><br>    &#125;,<br>    <span class="hljs-string">&quot;ok&quot;</span> : <span class="hljs-number">1</span><br>&#125;<br></code></pre></td></tr></table></figure>

<blockquote>
<p>tip: 关键点看： “stage” : “COLLSCAN”, 表示全集合扫描</p>
</blockquote>
<h3 id="4-4-2-涵盖的查询"><a href="#4-4-2-涵盖的查询" class="headerlink" title="4.4.2 涵盖的查询"></a>4.4.2 涵盖的查询</h3><p>Covered Queries，当查询条件和查询的投影仅包含索引字段时，MongoDB直接从索引返回结果，而不扫描任何文档或将文档带入内存。 这些覆盖的查询可以<br>非常有效。</p>
<p>例子</p>
<figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs php">db.comment.<span class="hljs-title function_ invoke__">find</span>(&#123;<span class="hljs-attr">userid</span>:<span class="hljs-string">&quot;1003&quot;</span>&#125;,&#123;<span class="hljs-attr">userid</span>:<span class="hljs-number">1</span>,<span class="hljs-attr">_id</span>:<span class="hljs-number">0</span>&#125;)<span class="hljs-comment">//查userid，不用_id,有userid的索引就不用回表</span><br></code></pre></td></tr></table></figure>

<h1 id="5-开发案例"><a href="#5-开发案例" class="headerlink" title="5.开发案例"></a>5.开发案例</h1><h2 id="5-1-需求分析"><a href="#5-1-需求分析" class="headerlink" title="5.1 需求分析"></a>5.1 需求分析</h2><p>文章示例参考：早晨空腹喝水，是对还是错？<a target="_blank" rel="noopener" href="https://www.toutiao.com/a6721476546088927748/">https://www.toutiao.com/a6721476546088927748/</a><br>需要实现以下功能：<br>1）基本增删改查API<br>2）根据文章id查询评论<br>3）评论点赞</p>
<h2 id="5-2-表结构分析"><a href="#5-2-表结构分析" class="headerlink" title="5.2 表结构分析"></a>5.2 表结构分析</h2><p>数据库：articledb</p>
<table>
<thead>
<tr>
<th>专栏文章评论</th>
<th>comment</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody><tr>
<td>字段名称</td>
<td>字段含义</td>
<td>字段类型</td>
<td>备注</td>
</tr>
<tr>
<td>_id</td>
<td>ID</td>
<td>ObjectId或String</td>
<td>Mongo的主键的字段</td>
</tr>
<tr>
<td>articleid</td>
<td>文章ID</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>content</td>
<td>评论内容</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>userid</td>
<td>评论人ID</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>nickname</td>
<td>评论人昵称</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>createdatetime</td>
<td>评论的日期时间</td>
<td>Date</td>
<td></td>
</tr>
<tr>
<td>likenum</td>
<td>回复数</td>
<td>Int32</td>
<td></td>
</tr>
<tr>
<td>replynum</td>
<td>状态</td>
<td>Int32</td>
<td></td>
</tr>
<tr>
<td>state</td>
<td>状态</td>
<td>String</td>
<td>0：不可见；1：可见；</td>
</tr>
<tr>
<td>parentid</td>
<td>上级ID</td>
<td>String</td>
<td>如果为0表示文章的顶级评论</td>
</tr>
</tbody></table>
<h2 id="5-3-技术选型"><a href="#5-3-技术选型" class="headerlink" title="5.3 技术选型"></a>5.3 技术选型</h2><h3 id="5-3-1-mongodb-driver"><a href="#5-3-1-mongodb-driver" class="headerlink" title="5.3.1 mongodb-driver"></a>5.3.1 mongodb-driver</h3><p>mongodb-driver是mongo官方推出的java连接mongoDB的驱动包，相当于JDBC驱动。我们通过一个入门的案例来了解mongodb-driver<br>的基本使用。<br>官方驱动说明和下载：<a target="_blank" rel="noopener" href="http://mongodb.github.io/mongo-java-driver/">http://mongodb.github.io/mongo-java-driver/</a><br>官方驱动示例文档：<a target="_blank" rel="noopener" href="http://mongodb.github.io/mongo-java-driver/3.8/driver/getting-started/quick-start/">http://mongodb.github.io/mongo-java-driver/3.8/driver/getting-started/quick-start/</a></p>
<h3 id="5-3-2-SpringDataMongoDB"><a href="#5-3-2-SpringDataMongoDB" class="headerlink" title="5.3.2 SpringDataMongoDB"></a>5.3.2 SpringDataMongoDB</h3><p>SpringData家族成员之一，用于操作MongoDB的持久层框架，封装了底层的mongodb-driver。<br>官网主页： <a target="_blank" rel="noopener" href="https://projects.spring.io/spring-data-mongodb/">https://projects.spring.io/spring-data-mongodb/</a></p>
<h2 id="5-4-文章微服务模块搭建"><a href="#5-4-文章微服务模块搭建" class="headerlink" title="5.4 文章微服务模块搭建"></a>5.4 文章微服务模块搭建</h2><p>（1）搭建项目工程article，pom.xml引入依赖：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-data-mongodb<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>（2）创建application.yml</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs java">spring:<br>    #数据源配置<br>    data:<br>        mongodb:<br>            # 主机地址<br>            host: <span class="hljs-number">192.168</span><span class="hljs-number">.40</span><span class="hljs-number">.141</span><br>            # 数据库<br>            database: articledb<br>            # 默认端口是<span class="hljs-number">27017</span><br>            port: <span class="hljs-number">27017</span><br>            #也可以使用uri连接<br>            #uri: mongodb:<span class="hljs-comment">//192.168.40.134:27017/articledb</span><br></code></pre></td></tr></table></figure>

<p>（3）创建启动类</p>
<h2 id="5-5-文章评论实体类的编写"><a href="#5-5-文章评论实体类的编写" class="headerlink" title="5.5 文章评论实体类的编写"></a>5.5 文章评论实体类的编写</h2><p>创建实体类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">//复合索引</span><br><span class="hljs-comment">// @CompoundIndex( def = &quot;&#123;&#x27;userid&#x27;: 1, &#x27;nickname&#x27;: -1&#125;&quot;)</span><br><span class="hljs-meta">@Document(collection=&quot;comment&quot;)</span><span class="hljs-comment">//可以省略，如果省略，则默认使用类名小写映射集合</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Comment</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Serializable</span> &#123;<br>    <span class="hljs-comment">//主键标识，该属性的值会自动对应mongodb的主键字段&quot;_id&quot;，如果该属性名就叫“id”,则该注解可以省略，否则必须写</span><br>    <span class="hljs-meta">@Id</span><br>    <span class="hljs-keyword">private</span> String id;<span class="hljs-comment">//主键</span><br>	<span class="hljs-meta">@Field(&quot;content&quot;)</span><span class="hljs-comment">//该属性对应mongodb的字段的名字，如果一致，则无需该注解</span><br>    <span class="hljs-keyword">private</span> String content;<span class="hljs-comment">//吐槽内容</span><br>	<span class="hljs-keyword">private</span> Date publishtime;<span class="hljs-comment">//发布日期</span><br>    <span class="hljs-meta">@Indexed</span>  <span class="hljs-comment">//添加了一个单字段的索引</span><br>	<span class="hljs-keyword">private</span> String userid;<span class="hljs-comment">//发布人ID</span><br>    <span class="hljs-keyword">private</span> String userid;<span class="hljs-comment">//发布人ID</span><br>    <span class="hljs-keyword">private</span> String nickname;<span class="hljs-comment">//昵称</span><br>    <span class="hljs-keyword">private</span> LocalDateTime createdatetime;<span class="hljs-comment">//评论的日期时间</span><br>    <span class="hljs-keyword">private</span> Integer likenum;<span class="hljs-comment">//点赞数</span><br>    <span class="hljs-keyword">private</span> Integer replynum;<span class="hljs-comment">//回复数</span><br>    <span class="hljs-keyword">private</span> String state;<span class="hljs-comment">//状态</span><br>    <span class="hljs-keyword">private</span> String parentid;<span class="hljs-comment">//上级ID</span><br>    <span class="hljs-keyword">private</span> String articleid;<br>    <span class="hljs-comment">//getter and setter.....</span><br>&#125;<br></code></pre></td></tr></table></figure>

<blockquote>
<p>tip: 索引可以提升查询效率，一般在查询字段上添加索引，索引的添加可以通过Mongo的命令来添加，也可以在Java的实体类中通过注解添加。</p>
</blockquote>
<blockquote>
<p>db.comment.createIndex({“userid”:1}) &#x2F;&#x2F;单字段索引注解@Indexed</p>
<p>db.comment.createIndex({“userid”:1,”nickname”:-1}) &#x2F;&#x2F;复合索引注解@CompoundIndex</p>
</blockquote>
<h2 id="5-6-文章评论的基本增删改查"><a href="#5-6-文章评论的基本增删改查" class="headerlink" title="5.6 文章评论的基本增删改查"></a>5.6 文章评论的基本增删改查</h2><p>（1）创建数据访问接口dao</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">//评论的持久层接口</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title class_">CommentRepository</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">MongoRepository</span>&lt;Comment,String&gt; &#123;<br>    <br>&#125;<br></code></pre></td></tr></table></figure>

<p>（2）创建业务逻辑类sevice包</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">//评论的业务层</span><br><span class="hljs-meta">@Service</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">CommentService</span> &#123;<br>    <span class="hljs-comment">//注入dao</span><br>    <span class="hljs-meta">@Autowired</span><br>    <span class="hljs-keyword">private</span> CommentRepository commentRepository;<br>    <br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">        * 保存一个评论</span><br><span class="hljs-comment">        * <span class="hljs-doctag">@param</span> comment</span><br><span class="hljs-comment">        */</span><br>        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">saveComment</span><span class="hljs-params">(Comment comment)</span>&#123;<br>        	commentRepository.save(comment);<br>        &#125;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">        * 更新评论</span><br><span class="hljs-comment">        * <span class="hljs-doctag">@param</span> comment</span><br><span class="hljs-comment">        */</span><br>        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">updateComment</span><span class="hljs-params">(Comment comment)</span>&#123;<br>       		 commentRepository.save(comment);<br>        &#125;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">        * 根据id删除评论</span><br><span class="hljs-comment">        * <span class="hljs-doctag">@param</span> id</span><br><span class="hljs-comment">        */</span><br>        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">deleteCommentById</span><span class="hljs-params">(String id)</span>&#123;<br>        	commentRepository.deleteById(id);<br>        &#125;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">        * 查询所有评论</span><br><span class="hljs-comment">        * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">        */</span><br>        <span class="hljs-keyword">public</span> List&lt;Comment&gt; <span class="hljs-title function_">findCommentList</span><span class="hljs-params">()</span>&#123;<br>       	 	<span class="hljs-keyword">return</span> commentRepository.findAll();<br>        &#125;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">        * 根据id查询评论</span><br><span class="hljs-comment">        * <span class="hljs-doctag">@param</span> id</span><br><span class="hljs-comment">        * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">        */</span><br>        <span class="hljs-keyword">public</span> Comment <span class="hljs-title function_">findCommentById</span><span class="hljs-params">(String id)</span>&#123;<br>            <span class="hljs-keyword">return</span> commentRepository.findById(id).get();<br>        &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h2 id="5-7-MongoTemplate实现评论点赞"><a href="#5-7-MongoTemplate实现评论点赞" class="headerlink" title="5.7 MongoTemplate实现评论点赞"></a>5.7 MongoTemplate实现评论点赞</h2><p>传统做法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">* 点赞-效率低</span><br><span class="hljs-comment">* <span class="hljs-doctag">@param</span> id</span><br><span class="hljs-comment">*/</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">updateCommentThumbupToIncrementingOld</span><span class="hljs-params">(String id)</span>&#123;<br>    <span class="hljs-type">Comment</span> <span class="hljs-variable">comment</span> <span class="hljs-operator">=</span> CommentRepository.findById(id).get();<br>    comment.setLikenum(comment.getLikenum()+<span class="hljs-number">1</span>);<br>    CommentRepository.save(comment);<br>&#125;<br></code></pre></td></tr></table></figure>

<blockquote>
<p>以上方法虽然实现简单，但是执行效率并不高，因为只需要将点赞数加1就可以了，没必要查询出所有字段修改后再更新所有字段。(蝴蝶效应)</p>
</blockquote>
<p>可以使用MongoTemplate类来实现对某列的操作</p>
<p>修改CommentService</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">//注入MongoTemplate</span><br><span class="hljs-meta">@Autowired</span><br><span class="hljs-keyword">private</span> MongoTemplate mongoTemplate;<br><span class="hljs-comment">/**</span><br><span class="hljs-comment">* 点赞数+1</span><br><span class="hljs-comment">* <span class="hljs-doctag">@param</span> id</span><br><span class="hljs-comment">*/</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">updateCommentLikenum</span><span class="hljs-params">(String id)</span>&#123;<br>    <span class="hljs-comment">//1.查询对象</span><br>    Query query=Query.query(Criteria.where(<span class="hljs-string">&quot;_id&quot;</span>).is(id));<br>    <span class="hljs-comment">//2.更新对象</span><br>    Update update=<span class="hljs-keyword">new</span> <span class="hljs-title class_">Update</span>();<br>    <span class="hljs-comment">//局部更新，相当于$set</span><br>    <span class="hljs-comment">// update.set(key,value)</span><br>    <span class="hljs-comment">//递增$inc</span><br>    <span class="hljs-comment">// update.inc(&quot;likenum&quot;,1);</span><br>    update.inc(<span class="hljs-string">&quot;likenum&quot;</span>);<br>    <span class="hljs-comment">//参数1：查询对象</span><br>    <span class="hljs-comment">//参数2：更新对象</span><br>    <span class="hljs-comment">//参数3：集合的名字或实体类的类型Comment.class</span><br>    mongoTemplate.updateFirst(query,update,<span class="hljs-string">&quot;comment&quot;</span>);<br>&#125;<br></code></pre></td></tr></table></figure>
                
              </div>
            
            <hr/>
            <div>
              <div class="post-metas my-3">
  
    <div class="post-meta mr-3 d-flex align-items-center">
      <i class="iconfont icon-category"></i>
      

<span class="category-chains">
  
  
    
      <span class="category-chain">
        
  <a href="/blog/categories/%E5%90%8E%E7%AB%AF%E6%8A%80%E6%9C%AF%E6%A0%88/" class="category-chain-item">后端技术栈</a>
  
  

      </span>
    
  
</span>

    </div>
  
  
    <div class="post-meta">
      <i class="iconfont icon-tags"></i>
      
        <a href="/blog/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/">#数据库</a>
      
    </div>
  
</div>


              
  

  <div class="license-box my-3">
    <div class="license-title">
      <div>MongoDB</div>
      <div>https://airfe.gitee.io/blog/2023/04/01/MongoDB/</div>
    </div>
    <div class="license-meta">
      
        <div class="license-meta-item">
          <div>作者</div>
          <div>Airfe</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>发布于</div>
          <div>2023年4月1日</div>
        </div>
      
      
      
        <div class="license-meta-item">
          <div>许可协议</div>
          <div>
            
              
              
                <a target="_blank" href="https://creativecommons.org/licenses/by/4.0/">
                  <span class="hint--top hint--rounded" aria-label="BY - 署名">
                    <i class="iconfont icon-by"></i>
                  </span>
                </a>
              
            
          </div>
        </div>
      
    </div>
    <div class="license-icon iconfont"></div>
  </div>



              
                <div class="post-prevnext my-3">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/blog/2023/04/10/Webpack%EF%BC%88%E4%BA%8C%EF%BC%89%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%BC%98%E5%8C%96/" title="Webpack生产环境优化">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">Webpack生产环境优化</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/blog/2023/04/01/Node.js/" title="Node.js">
                        <span class="hidden-mobile">Node.js</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
  
  
    <article id="comments" lazyload>
      
  <div id="valine"></div>
  <script type="text/javascript">
    Fluid.utils.loadComments('#valine', function() {
      Fluid.utils.createScript('https://lib.baomitu.com/valine/1.5.1/Valine.min.js', function() {
        var options = Object.assign(
          {"appId":"RW68dMkEpeIOJJiBr1lPkhOS-gzGzoHsz","appKey":"P5fzMTGSJIoTaGvmgzsUHeNZ","path":"window.location.pathname","placeholder":"发表你的看法吧~","avatar":"retro","meta":["nick","mail","link"],"requiredFields":[],"pageSize":10,"lang":"zh-CN","highlight":false,"recordIP":false,"serverURLs":"","emojiCDN":null,"emojiMaps":null,"enableQQ":false,"appid":"RW68dMkEpeIOJJiBr1lPkhOS-gzGzoHsz","appkey":"P5fzMTGSJIoTaGvmgzsUHeNZ","server_url":"https://rw68dmke.lc-cn-n1-shared.com"},
          {
            el: "#valine",
            path: window.location.pathname
          }
        )
        new Valine(options);
        Fluid.utils.waitElementVisible('#valine .vcontent', () => {
          var imgSelector = '#valine .vcontent img:not(.vemoji)';
          Fluid.plugins.imageCaption(imgSelector);
          Fluid.plugins.fancyBox(imgSelector);
        })
      });
    });
  </script>
  <noscript>Please enable JavaScript to view the comments</noscript>


    </article>
  


          </article>
        </div>
      </div>
    </div>

    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar" style="margin-left: -1rem">
    <div id="toc">
  <p class="toc-header">
    <i class="iconfont icon-list"></i>
    <span>目录</span>
  </p>
  <div class="toc-body" id="toc-body"></div>
</div>



  </aside>


    </div>
  </div>
</div>





  



  



  



  



  







    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v" for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>

    

    
  </main>

  <footer>
    <div class="footer-inner">
  
    <div class="footer-content">
        <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> <div style="font-size: 0.85rem"> <span id="timeDate">载入天数</span> <span id="times">载入时分秒</span> <script src="js/duration.js"></script> </div> 
    </div>
  
  
    <div class="statistics">
  
  

  
    
      <span id="leancloud-site-pv-container" style="display: none">
        总访问量 
        <span id="leancloud-site-pv"></span>
         次
      </span>
    
    
      <span id="leancloud-site-uv-container" style="display: none">
        总访客数 
        <span id="leancloud-site-uv"></span>
         人
      </span>
    
    

  
</div>

  
  
    <!-- 备案信息 ICP for China -->
    <div class="beian">
  <span>
    <a href="http://beian.miit.gov.cn/" target="_blank" rel="nofollow noopener">
      蜀ICP备2023008943号
    </a>
  </span>
  
    
      <span>
        <a
          href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=https://beian.miit.gov.cn/"
          rel="nofollow noopener"
          class="beian-police"
          target="_blank"
        >
          
            <span style="visibility: hidden; width: 0">|</span>
            <img src="" srcset="/blog/img/loading.gif" lazyload data-original="/blog/img/police_beian.png" alt="police-icon"/>
          
          <span>京公网安备12345678号</span>
        </a>
      </span>
    
  
</div>

  
  
</div>

  </footer>

  <!-- Scripts -->
  
  <script  src="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js" ></script>
<script  src="https://lib.baomitu.com/twitter-bootstrap/4.6.1/js/bootstrap.min.js" ></script>
<script  src="/blog/js/events.js" ></script>
<script  src="/blog/js/plugins.js" ></script>


  <script  src="https://lib.baomitu.com/typed.js/2.0.12/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var subtitle = document.getElementById('subtitle');
      if (!subtitle || !typing) {
        return;
      }
      var text = subtitle.getAttribute('data-typed-text');
      
        typing(text);
      
    })(window, document);
  </script>




  
    <script  src="/blog/js/img-lazyload.js" ></script>
  




  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/tocbot/4.18.2/tocbot.min.js', function() {
    var toc = jQuery('#toc');
    if (toc.length === 0 || !window.tocbot) { return; }
    var boardCtn = jQuery('#board-ctn');
    var boardTop = boardCtn.offset().top;

    window.tocbot.init(Object.assign({
      tocSelector     : '#toc-body',
      contentSelector : '.markdown-body',
      linkClass       : 'tocbot-link',
      activeLinkClass : 'tocbot-active-link',
      listClass       : 'tocbot-list',
      isCollapsedClass: 'tocbot-is-collapsed',
      collapsibleClass: 'tocbot-is-collapsible',
      scrollSmooth    : true,
      includeTitleTags: true,
      headingsOffset  : -boardTop,
    }, CONFIG.toc));
    if (toc.find('.toc-list-item').length > 0) {
      toc.css('visibility', 'visible');
    }

    Fluid.events.registerRefreshCallback(function() {
      if ('tocbot' in window) {
        tocbot.refresh();
        var toc = jQuery('#toc');
        if (toc.length === 0 || !tocbot) {
          return;
        }
        if (toc.find('.toc-list-item').length > 0) {
          toc.css('visibility', 'visible');
        }
      }
    });
  });
</script>


  <script src=https://lib.baomitu.com/clipboard.js/2.0.11/clipboard.min.js></script>

  <script>Fluid.plugins.codeWidget();</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/anchor-js/4.3.1/anchor.min.js', function() {
    window.anchors.options = {
      placement: CONFIG.anchorjs.placement,
      visible  : CONFIG.anchorjs.visible
    };
    if (CONFIG.anchorjs.icon) {
      window.anchors.options.icon = CONFIG.anchorjs.icon;
    }
    var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
    var res = [];
    for (var item of el) {
      res.push('.markdown-body > ' + item.trim());
    }
    if (CONFIG.anchorjs.placement === 'left') {
      window.anchors.options.class = 'anchorjs-link-left';
    }
    window.anchors.add(res.join(', '));

    Fluid.events.registerRefreshCallback(function() {
      if ('anchors' in window) {
        anchors.removeAll();
        var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
        var res = [];
        for (var item of el) {
          res.push('.markdown-body > ' + item.trim());
        }
        if (CONFIG.anchorjs.placement === 'left') {
          anchors.options.class = 'anchorjs-link-left';
        }
        anchors.add(res.join(', '));
      }
    });
  });
</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js', function() {
    Fluid.plugins.fancyBox();
  });
</script>


  <script>Fluid.plugins.imageCaption();</script>

  <script defer src="/blog/js/leancloud.js" ></script>

  <script  src="/blog/js/local-search.js" ></script>





<!-- 主题的启动项，将它保持在最底部 -->
<!-- the boot of the theme, keep it at the bottom -->
<script  src="/blog/js/boot.js" ></script>


  

  <noscript>
    <div class="noscript-warning">博客在允许 JavaScript 运行的环境下浏览效果更佳</div>
  </noscript>

        <style>
            [bg-lazy] {
                background-image: none !important;
                background-color: #eee !important;
            }
        </style>
        <script>
            window.imageLazyLoadSetting = {
                isSPA: false,
                preloadRatio: 1,
                processImages: null,
            };
        </script><script>window.addEventListener("load",function(){var t=/\.(gif|jpg|jpeg|tiff|png)$/i,r=/^data:image\/[a-z]+;base64,/;Array.prototype.slice.call(document.querySelectorAll("img[data-original]")).forEach(function(a){var e=a.parentNode;"A"===e.tagName&&(e.href.match(t)||e.href.match(r))&&(e.href=a.dataset.original)})});</script><script>!function(r){r.imageLazyLoadSetting.processImages=t;var e=r.imageLazyLoadSetting.isSPA,n=r.imageLazyLoadSetting.preloadRatio||1,c=a();function a(){var t=Array.prototype.slice.call(document.querySelectorAll("img[data-original]")),e=Array.prototype.slice.call(document.querySelectorAll("[bg-lazy]"));return t.concat(e)}function t(){e&&(c=a());for(var t,o=0;o<c.length;o++)0<=(t=(t=c[o]).getBoundingClientRect()).bottom&&0<=t.left&&t.top<=(r.innerHeight*n||document.documentElement.clientHeight*n)&&function(){var t,e,n,a,i=c[o];e=function(){c=c.filter(function(t){return i!==t}),r.imageLazyLoadSetting.onImageLoaded&&r.imageLazyLoadSetting.onImageLoaded(i)},(t=i).hasAttribute("bg-lazy")?(t.removeAttribute("bg-lazy"),e&&e()):(n=new Image,a=t.getAttribute("data-original"),n.onload=function(){t.src=a,t.removeAttribute("data-original"),e&&e()},t.src!==a&&(n.src=a))}()}function i(){clearTimeout(t.tId),t.tId=setTimeout(t,500)}t(),document.addEventListener("scroll",i),r.addEventListener("resize",i),r.addEventListener("orientationchange",i)}(this);</script></body>
</html>
